5月29日、Brandon Dong氏が「Why are 2025/05/28 and 2025-05-28 different days in JavaScript?」と題した記事を公開した。この記事では、JavaScript Date
コンストラクタが日付文字列をどのように解釈するかによって“同じように見える日付”が異なるカレンダー日へ変換される仕組みと、その歴史的経緯について詳しく紹介されている。以下に、その内容を紹介する。

ローカル時刻と UTC で揺れる Date
の挙動
まず筆者は、次のコード片で現象を示している。
console.log(new Date('2025/05/28').toDateString());
console.log(new Date('2025-05-28').toDateString());
console.log(new Date('2025-5-28').toDateString());
スラッシュ区切り(2025/05/28
)はローカル時刻として解釈されるが、ハイフン区切り(2025-05-28
)は ISO 8601 形式と見なされ UTC でパースされるため、タイムゾーンが日本標準時(UTC+9)の場合は前日 “2025-05-27” になる――というのが問題の核心だ。
const date = new Date('2025/05/28');
console.log(date); // ローカル時刻基準
console.log(date.toDateString());
const utcDate = new Date('2025-05-28');
console.log(utcDate); // UTC 基準
console.log(utcDate.toDateString());
仕様と実装が右往左往した 15 年の歴史
筆者は Chrome/Firefox/Safari の実装と ECMA-262 の改訂履歴を精査し、以下のタイムラインを整理している。
- 2009 年 ― 各ブラウザは多様なフォーマットをローカル時刻で受理していた。
- ES5(2009 年末) ― ISO 8601 由来の新しい標準フォーマットを要求。しかしオフセット省略時の挙動は「ローカルでも UTC でもよい」と曖昧。
- Firefox ― 日付だけの形式を UTC、時刻付きかつオフセットなしの形式をローカルと解釈する実装を採用。
- Chrome ― 両方ローカルで実装。
- Safari ― すべてのフィールドが揃わないと拒否するバグを抱えた実装でリリース。
- ES5.1(2011 年) ― 「オフセットが無いときは Z」と追記。
- Chrome ― 両方 UTC に変更。
- Safari ― バグ修正後、両方 UTC に。
- ES6(2015 年) ― 「オフセットが無い場合はローカル」を再び明記。
- Chrome ― 両方ローカルに戻す。
- Chrome ― 互換性問題の報告を受け、変更を取り消す。
- TC39 議論 ― 日付だけ(YYYY-MM-DD)は UTC、時刻付きかつオフセットなしはローカルで決着。
- ES7(2016 年)以降 ― 各ブラウザが Firefox 式(上記仕様)へ順次揃い、現在に至る。
この間、特に Chrome の挙動は local → UTC → local → UTC → local と迷走した。
Temporal API がもたらす“曖昧さゼロ”の世界
Date
は「常にタイムスタンプ(ミリ秒)」という設計ゆえ、日付単体を扱いたい場面でも暗黙的にタイムゾーンが絡む。次期標準 Temporal ではこれを解消するため、純粋な日付を表す Temporal.PlainDate
が導入される。
import { PlainDate } from '@js-temporal/polyfill';
const xmas = PlainDate.from('2025-12-25'); // ただの 12 月 25 日
一方、Temporal.Instant
に変換したい場合は 必ず Z
かタイムゾーン ID を明示しなければエラーになる仕様で、過去の混乱を再発させない設計になっている。
ブラウザのパーサは意外なほど寛容
最後に筆者は “お遊び” として、次のような文字列すら有効日付として受理される例を挙げる。
const date = 'it is wednesday, my dudes. 2025, April, maybe...28(?)';
console.log(new Date(date)); // → 2025-05-?? 月名とコンマで判別
英語テキストが混ざっていても月名と年が拾えればパースできてしまう点は、多くの開発者にとって驚きである。
詳細は[Why are 2025/05/28 and 2025-05-28 different days in JavaScript?」を参照していただきたい。