HOWTO · JavaScript
JavaScript で文字列を日付に変換する
このチュートリアルでは、文字列を日付に変換する JavaScript のさまざまな方法を示します。
このページの内容
データベースやAPIから取得した日付は文字列のままなので、日付選択 UI や計算で JavaScript の Date オブジェクトが必要になることがあります。適切な変換方法は、入力形式とタイムゾーンが明示されているかどうかによって異なります。対応している標準形式の文字列を解析するには、文字列を new Date(dateString) の引数として渡します。引数なしの new Date() は現在時刻の Date を作成します。ミリ秒が必要なら Date.parse() を使い、既知のカスタム形式なら各要素を自分で解析します。
このガイドでは、実用的な方法を3つ紹介します。
- 対応している日付文字列を
new Date(dateString)に渡して、Dateオブジェクトを作成する。 - 数値のミリ秒が必要な場合に
Date.parse()を呼び出す。 - 既知のカスタム形式を要素に分割してから、
Dateを作成する。
JavaScriptで文字列をDateに変換するにはnew Date()を使う
new Date(dateString) コンストラクターは、対応している日付文字列を受け取り、Date オブジェクトを返します。この ISO 8601 タイムスタンプには、UTCを示す Z が含まれています。toISOString() を呼び出すと、実行環境のローカルタイムゾーンにかかわらず、そのUTC時刻が返されます。
const dateString = '2024-05-23T14:30:00Z';
const date = new Date(dateString);
console.log(date instanceof Date);
console.log(date.toISOString());
2024-05-23 のような日付のみの文字列はUTCとして解釈されます。一方、オフセットのない日時文字列はローカル時刻として解釈されます。入力が特定の時点を表す場合は、実行環境のローカルタイムゾーンに左右されないよう、オフセットを明示した標準形式の文字列を使ってください。
標準的な日時形式以外の解析方法は、JavaScriptの実装間で一貫して定義されていません。あるブラウザーやランタイムで受け入れられる文字列でも、別の環境では異なる解釈になることがあります。使用する前に、Number.isNaN(date.getTime()) で結果のオブジェクトを確認してください。また、解析に成功しても、文字列がアプリケーションで必要な形式や暦上のルールに従っているとは限りません。そうした要件は別途検証してください。コード例と出力例に含まれる表示ラベルは、コードブロックを原文のまま保持しているため英語です。
JavaScriptで日付文字列を解析するにはDate.parse()を使う
Date.parse() は、解析できた日付文字列についてUNIXエポックからの経過時間をミリ秒数で返し、入力を解析できない場合は NaN を返します。返されるのは数値であり、Date オブジェクトではありません。APIの値からオブジェクトが必要な場合は、値を解析し、その数値を使って日付を作成します。
const apiValue = '2019-01-01T12:30:00.000Z';
const milliseconds = Date.parse(apiValue);
console.log(typeof milliseconds);
console.log(Number.isNaN(milliseconds) ? 'not parsed' : new Date(milliseconds).toISOString());
Number.isNaN() を使うと、解析に失敗したことを示す値を検出できますが、アプリケーション固有の形式を完全に検証できるわけではありません。ランタイムが受け入れても、アプリケーションでは拒否すべき値があるかもしれません。入力に特定のパターンが求められる場合は、解析結果を使う前に、そのパターンと暦上の値を確認してください。
文字列を分割してJavaScriptのDateに変換する
入力が既知のカスタム形式の場合は、その形式に従って文字列を分割し、各要素を複数の引数を取る Date コンストラクターに渡します。この例では DD-MM-YYYYTHH:mm:ss の形式を想定しており、コンストラクターは各要素をローカル時刻として解釈します。要素が実在する暦日を表さない場合は null を返します。
function parseKnownDate(value) {
if (typeof value !== 'string') {
return null;
}
const dateTimeParts = value.split('T');
if (dateTimeParts.length !== 2) {
return null;
}
const [datePart, timePart] = dateTimeParts;
if (
!/^\d{2}-\d{2}-\d{4}$/.test(datePart) ||
!/^\d{2}:\d{2}:\d{2}$/.test(timePart)
) {
return null;
}
const dateParts = datePart.split('-');
const timeParts = timePart.split(':');
if (dateParts.length !== 3 || timeParts.length !== 3) {
return null;
}
const [day, month, year] = dateParts.map(Number);
const [hours, minutes, seconds] = timeParts.map(Number);
if (![day, month, year, hours, minutes, seconds].every(Number.isInteger)) {
return null;
}
// The multi-argument constructor treats years 0–99 as 1900–1999.
// setFullYear preserves the supplied year, including values in that range.
const date = new Date(0);
date.setFullYear(year, month - 1, day);
date.setHours(hours, minutes, seconds, 0);
if (
date.getFullYear() !== year ||
date.getMonth() !== month - 1 ||
date.getDate() !== day ||
date.getHours() !== hours ||
date.getMinutes() !== minutes ||
date.getSeconds() !== seconds
) {
return null;
}
return date;
}
const date = parseKnownDate('21-03-2020T11:20:30');
console.log(date === null ? 'not a valid date' : date.toString());
分割処理は、指定された要素の順序を前提としています。入力元で順序や区切り文字が異なる場合は、それに合わせて調整してください。月の引数は0から始まるため、コードでは人が読む月の値から1を引いています。セッターはローカル時刻を使い、範囲外の値を繰り上げ・繰り下げて正規化することがあります。設定後の各要素を解析した値と比較すれば、その正規化を検出できます。初期の日付はローカルタイムゾーンに基づくため、この方法で作られるのはローカル時刻の値であり、UTCタイムスタンプではありません。年が 0 から 99 の範囲になる可能性がある場合は、setFullYear() を使うと複数引数のコンストラクターによる特別な年の扱いを避けられます。この例では整数の各要素と暦日の繰り上がりを確認します。より厳密な入力規則が必要なアプリケーションでは、文字列全体の形式と各項目に許可する範囲も確認してください。
まとめ
対応している日付文字列を new Date(dateString) に渡すと Date オブジェクトを作成できます。特定の時点を表す文字列には、オフセットを明示するのがおすすめです。引数なしの new Date() は現在時刻の Date を作成するもので、文字列を解析するものではありません。UNIXエポックからのミリ秒数、または解析失敗を示す NaN が必要なら Date.parse() を使います。解析に成功した数値から Date オブジェクトを作るには、new Date(milliseconds) に渡してください。既知のカスタム形式では、ローカル時刻の日付を作成する前に各要素を解析して検証します。ISO 8601の概要では、多くのAPIで使われる日付と時刻の表記を説明しています。