0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ISOフォーマット文字列の日付が存在するかチェックする

Posted at

行いたいこと

  • 2/31のような存在しない日付が入力されたときに日付の存在チェック
  • 入力値はISOフォーマットの文字列

弊害となっていること

  • Number.isNaN(new Date(isoString).getTime())は2/31のような日付の場合にチェック漏れしてしまう。
  • ISOフォーマットには末尾にタイムゾーンを表す文字列があり、この文字列次第で日付の正規表現抽出し、new Date(iso)で作成したDateオブジェクトのgetDateで比較を行う処理に失敗する。

対処方法

  • チェック時のみタイムゾーンをZに置き換えて日付を比較する

サンプルコード

/**
 * ISOフォーマット文字列の検証
 * @param {*} isoString ISOフォーマット文字列
 * @returns 警告判定
 */
export const isoValidator = (isoString) => {
    // タイムゾーンを無視するため強制的に末尾をZに置き換える
    const enforceUtcIso = isoString.replace(/[+|-]\d{1,2}:\d{1,2}$/, "Z");
    // isoフォーマットが正常か判定する (例: 2023-01-01T01:02:03.444Z)
    const match = enforceUtcIso.match(
            /^(\d{4})-(\d{2})-(\d{2})T(0[0-9]|1[0-9]|2[0-3]):([0-5]\d):([0-5]\d)(.\d+Z|Z)$/
        );

    if (match == null || match.length < 8) {
        // isoフォーマットに不正確な部分がある場合
        return true;
    }

    const parsedDate = new Date(enforceUtcIso);
    if (Number.isNaN(parsedDate.getTime())) {
        // ISO文字列のパースに失敗した場合
        return true;
    }

    return (
        parsedDate.getUTCFullYear() !== parseInt(match[1], 10) ||
        (parsedDate.getUTCMonth() + 1) !== parseInt(match[2], 10) ||
        parsedDate.getUTCDate() !== parseInt(match[3], 10)
    );
};
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?