Skip to content

Instantly share code, notes, and snippets.

@wtnabe
Last active August 28, 2023 02:22
Show Gist options
  • Save wtnabe/c65196d4572bf0b92a88965feb47a7ce to your computer and use it in GitHub Desktop.
Save wtnabe/c65196d4572bf0b92a88965feb47a7ce to your computer and use it in GitHub Desktop.
JavaScript local "Date" object

JavaScript の Date の扱いが面倒という話。

個人的には

結局中身は UTC の unixtime ですよと言われれば、あーなるほどという感じ

かなと思うんだけど、一方で以下の部分がつらいなと思った。

  • Date と言いつつ中身は Time で、Date を表現する方法がない
  • new Date(YYYY, MM, DD) の MM が 0 origin

欲しいものがないならいったん作りましょうということでできたのでこれ。

/**                                                                                 
 * @param {string} dateString YYYY-MM-DD                                            
 * @returns {Date}                                                                  
 */
function parseDateWithLocalTZ (dateString) {
  const d = new Date(dateString)

  return new Date(d.getFullYear(), d.getMonth(), d.getDate())
}

普通に string で日付を与えて Date オブジェクトを作りたいんだけど、なんでこんなものが欲しかったのかというと、

  • Date はローカルの TZ でしか Date オブジェクトを作れません ← 文字列を与える場合はそうとは限らない
  • 文字列で Date を初期化する場合は実は挙動が分かれる
    1. 時刻まで書いている場合は、TZ 表記を省略するとローカルの TZ が採用される(ローカルTZ基準の挙動が正なら納得)
    2. 時刻を省略してしまうと UTC になる

1 は Node.js だと以下のような感じ。

> new Date('2023-08-01T00:00:00')
2023-07-31T15:00:00.000Z

この挙動は ISO 8601 とも合致しているはず。

2 も同様に実行してみると、

> new Date('2023-08-01')
2023-08-01T00:00:00.000Z

あれ? UTC として解釈されて返ってくる。たまたま「日付」の単位で処理を書きたかったので、お? となった。ここら辺の謎い挙動だけなんとかしてほしいなぁと思った。

上の関数を使うと

> parseDateWithLocalTZ('2023-08-01')
2023-07-31T15:00:00.000Z

で期待通り。

もう一つ加えるとしたら Invalid Date で、上のコードは Invalid Date の場合、そのままスルーで Invalid Date が返ってくるので、

JavaScript で Invalid Date を判定する

この辺のノウハウを活かしてなんとかするしかない。

Detecting an "invalid date" Date instance in JavaScript - Stack Overflow

とか見ると、昔からみんな混乱してるんだなと分かる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment