JSのDateに渡せる文字列のパターンが複雑なので網羅してみる

JSのDateに渡せる文字列のパターンが複雑なので網羅してみる

2024-05-2512 min read

目次

  1. 概要
  2. パターン
  3. 推測される仕様

概要

JS の Date に渡せる文字列のパターン ↓

// 例
new Date("2024-01-01");
new Date("2024/01/01");
new Date("2024-01-01 00:00:00");

これが非常に複雑なので整理してみることにしました。

扱わないこと

この検証ではタイムゾーン(タイムゾーンがズレるとかズレないとか) のことについては触れません。

この話が加わるとさらにややこしくなるからです。

あくまでも、Date でパースできるかどうかという部分に焦点を絞っています。

パターン

デタラメにさまざまな文字を入力して試してみた結果、次のパターンを許容することがわかりました。

const str = [
  // YYYY-mm-dd hh:mi:ss
  /// ISO 8601
  "2020-01-01 00:00:00",
  "2020-01-01T00:00:00",
  "2020-01-01T00:00:00Z",
  "2020-01-01T00:00:00+0900",
  "2020-01-01T00:00:00+09:00",
  "2020-01-01T00:00:00-09:00",
  "2020-01-01 00:00:00.000",
  "2020-01-01 00:00:00.000Z",
  "2020-01-01 00:00:00.000+0000",
  "2020-01-01 00:00:00.000+00:00",
  "2020-01-01 00:00:00.000-00:00",
  "2020-01-01 00:00:00.000+0000 ",
  "2020-01-01 00:00:00.000+0000 (test)",
  /// RFC 2822
  "Wed Jan 01 2020 00:00:00 GMT+0900 (日本標準時)",
  "Wed Jan 01 2020 00:00:00 GMT+0000 (GMT)",
  "Wed Jan 01 2020 00:00:00 GMT+09:00 (日本標準時)",
  "Wed Jan 01 2020 00:00:00 GMT+09:00 (Hello World!)",
  "Wed Jan 01 2020 00:00:00 GMT+09:00 (テストです〜)",
  "Wed Jan 01 2020",
  "2020:01:01",
  // YYYY-MM-DD
  "2020-01-01",
  "2020/01/01",
  "2020,01,01",
  "2020.01.01",
  "2020;01;01",
  "2020=01=01",
  "2020@01@01",
  "2020#01#01",
  "2020&01&01",
  "2020%01%01",
  "2020!01!01",
  "2020<01<01",
  "2020>01>01",
  "2020*01*01",
  "2020(01(01",
  "2020$01$01",
  "2020 01 01",
  "2020  01  01",
  "2020 01 01",
  "2020  .01  .01",
  "2020/,.;=@#&%<>*($ 01/,.;=@#&%<>*($ 01",
  "2020/,.;=@#&%<>*($ 01/,.;=@#&%<>*($ 01T00:00:00",
  "////2020///01//01/",
  "2020***01***01",
  " 2020-01-01",
  "     2020-01-01",
  ".2020-01-01",
  "   2020-01-01   ",
  "/,.;=@#&%<>* 2020-01-01",
  "2020-01-01 ",
  "2020-01-01  ",
  "2020-01-01/,.;=@#&%<>*($",
  "A 2020-01-01",
  "ABC 2020-01-01",
  "abc 2020-01-01",
  "ABCDEFGHIJKLMNOPQRSTUVWXYZ 2020-01-01",
  "A b C 2020-01-01",
  "01 01 2020",
  "01-01-2020",
  "ABC 01-01-2020",
  "A B C 01-01-2020",
  "Jan 01 2020",
  "2020 Jan 01 ",
  "2020-Jan-01 ",
  "2020 January 01 ",
  "2020 01 01 00:00:00",
  "2020/,.;=@#&%<>*($01/,.;=@#&%<>*($01/,.;=@#&%<>*($00:00:00",
  "2020\n01\n01",
  "2020\001\001",
  "2020-01-01 (^_^)/",
  "(^_^)/ 2020-01-01",
  "2020-01-01 (^Д^)",
  "2020-01-01 (((^-^)))",
  // YYYY-MM
  "2020-01",
  "2020 01",
  "2020/01",
  "202001",
  "202001Z",
  "202001 (test)",
  // YYYY
  "2020",
  "0",
  "1",
  "-1",
  "+1",
  "+2020",
  "2020-",
  "2020#",
  "$2020",
];

また、ダメだったパターンは以下となりました。

const str = [
  "2020-01-01 T 00:00:00-09:00",
  "2020-01-01T00:00:00+00:00Z",
  "2020-01-01T00:00:00+00:00 ",
  "2020:01:01T00:00:00",
  "2020--01--01",
  "2020/-01/-01",
  "2020 -01 -01",
  "2020~01~01",
  "2020+01+01",
  "2020_01_01",
  "2020|01|01",
  "2020\\01\\01",
  "2020)01)01",
  "20200101",
  "2020-01-01+09:00",
  "1577836800000",
  "(^_^)/",
  "\\(^_^)/",
  "\2\0\2\0-\0\1-\0\1",
  "(/,.;=@#&%<>* 2020-01-01",
  "/,.;=@#&%<>*( 2020-01-01",
  "¥2020",
  "202001+00:00",
];

推測される仕様

デタラメに試したパターンから推測される仕様は以下の要素を含むと考えられます

  • ISO 8601 形式のサポート
  • RFC 2822 形式のサポート
  • YYYY-mm-dd 箇所において多様な区切り文字を許容
    • / . , ; = @ # & % ! < > * ( $ などの特殊文字を許容
    • 前後の空白や特殊文字の許容
    • 時分秒ミリ秒の区切り形式は厳格
  • 前後の空白や特殊文字を無視する
  • カッコ内は無効なものとして扱われる

これより厳密な仕様を把握するためにはソースコードを見てみないとという感じですね。

終わり。

Author
githubzennqiita
ただの備忘録です。

※外部送信に関する公表事項