意外と知られていないJavaScriptのnew Date()の使用方法

new Date()の使い方

指定した時刻を表す日付オブジェクトを生成する。何も指定されなかった場合は現在の(デバイスに)設定されている時刻を取得する。
日時を指定するときはYYYY/MM/DD HH:mm:ssまたはそれぞれをカンマで区切った形式で取得。

var d1 = new Date('2014/04/01 12:34:56');
console.log(d1);
// => Tue Apr 01 2014 12:34:56 GMT+0900

var d2 = new Date(2014, 3, 1, 12, 34, 56);
console.log(d2);
// => Tue Apr 01 2014 12:34:56 GMT+0900

new Date()に年を入れる

new Date("2013")でその年の1月1日GMT+9時間の日付を取得する

var d2 = new Date("2013");
console.log(d2);
// => Tue Jan 01 2013 09:00:00 GMT+0900

new Date()に年と月は入れられない

new Date("2013/01")はエラーになる

var d3 = new Date("2013/01");
console.log(d3);
// => Invalid Date

追記: 最近のChromeはTue Jan 01 2013 00:00:00 GMT+0900 (日本標準時)を返し、Node.jsは2012-12-31T15:00:00.000Zを返す。

new Date()に年月日を入れる

new Date("2013/01/23")で取得。月の0は省略可能。

var d4 = new Date("2013/1/23");
console.log(d4);
// => Wed Jan 23 2013 00:00:00 GMT+0900

var d5 = new Date("2013/01/23");
console.log(d5);
// => Wed Jan 23 2013 00:00:00 GMT+0900

new Date(2015, 2, 0)で最後の日を取得

例えばnew Date(2015, 2, 0)のように第3引数に0を指定すると2月の最後の日が取得できる。getDate()を併用してその月の最大日数を取得するのによく利用される。

var d = new Date(2015, 2, 0);
console.log(d);
// => Sat Feb 28 2015 00:00:00 GMT+0900

console.log(d.getDate());
// => 28

これを利用すればうるう年の判定も簡単にできる。

function isLeapYear(year) {
  return new Date(year, 2, 0).getDate() === 29;
}

console.log(isLeapYear(2015));
// => false

console.log(isLeapYear(2020));
// => true

new Dateの年は4桁以外も入れられる

new Dateの年をnew Date(99, 0, 1)にすると1999年が返ってくる。しかし、new Date(100, 0, 1)は2000年ではなく100年になってしまうため、年を4桁以外で入力しないほうが良い。

var d1 = new Date(0, 0, 1);
console.log(d1);
// => Mon Jan 01 1900 00:00:00 GMT+0900 (JST)

var d2 = new Date(99, 0, 1);
console.log(d2);
// => Fri Jan 01 1999 00:00:00 GMT+0900 (JST)

var d3 = new Date(100, 0, 1);
console.log(d3);
// => Fri Jan 01  100 00:00:00 GMT+0900 (JST)

new Date()で年月日の区切りをハイフンにしないほうが良い

new Date("2013-01-23")だと00:00ではなく09:00になるので使用しないほうが良い。

var d6 = new Date("2013-01-23");
console.log(d6);
// => Wed Jan 23 2013 09:00:00 GMT+0900

var d66 = new Date("2013/01/23");
console.log(d66);
// => Wed Jan 23 2013 00:00:00 GMT+0900

new Date()に年月日と時間を入れる

秒は省略可能だが分は省略不可

var d7 = new Date("2013/01/23 12");
console.log(d7);
// => Invalid Date

var d8 = new Date("2013/01/23 12:34");
console.log(d8);
// => Wed Jan 23 2013 12:34:00 GMT+0900

var d9 = new Date("2013/01/23 12:34:56");
console.log(d9); 
// => Wed Jan 23 2013 12:34:56 GMT+0900

getTime()でミリ秒を取得

日時を指定しない場合は(new Date).getTime()という書き方も可能

var now1 = new Date("2013/01/23 12:34").getTime();
console.log(now1);
// => 1358912040000

var now2 = (new Date).getTime();
console.log(now2);
// => 現在の日時がミリ秒で表示される

getTime()を使わずミリ秒を取得

一般的にはミリ秒の取得にはgetTime()が使用されることが多いが、現在の時刻をミリ秒で取得したい場合は+new DateまたはDate.now()でもミリ秒を取得できる。

+new DateまたはDate.now()でミリ秒を取得したサンプル

処理時間の算出にはDate.now()を使用するのが良いだろう。

5マイクロ秒の超高精度で計測したい場合はperformance.now()を使用する。

// Date.now()で処理時間算出
const startTime = Date.now();
setTimeout(() => {
  console.log(Date.now() - startTime);
}, 1000);
// => 1001

// performance.now()で処理時間算出
const performanceTime = performance.now();
setTimeout(() => {
  console.log(performance.now() - performanceTime);
}, 1000);
// => 1001.1150000000007

日時の比較

たまにミリ秒に変換してから比較しているコードを見かけることがあるがミリ秒に変換せずにそのまま変数に代入してif文で比較できる。

var a = new Date("2013/01/23 12:34");
var b = new Date("2013/01/23 12:35");

// 結果はb is bigger than a
if(a > b){
  console.log('a is bigger than b');
}
else{
  console.log('b is bigger than a');
}

ただし、等価演算子(==や===)を使用した場合は同じ日付でもfalseが返されるため、この場合はgetTime()でミリ秒に変換する必要がある。

var a = new Date("2000/01/01 00:00:00");
var b = new Date("2000/01/01 00:00:00");

console.log(a == b);
// => false

console.log(a === b);
// => false

var aa = new Date("2000/01/01 00:00:00").getTime();
var bb = new Date("2000/01/01 00:00:00").getTime();

console.log(aa == bb);
// => true

console.log(aa === bb);
// => true

new Date同士の減算

new Date同士を減算するとミリ秒(数値)になる。加算すると文字列になってしまうので足しても意味がない。

var a = new Date("2015/01/01 00:00");
var b = new Date("2014/01/01 00:00");

console.log(a - b);
// => 31536000000

console.log(a + b);
// => Thu Jan 01 2015 00:00:00 GMT+0900Wed Jan 01 2014 00:00:00 GMT+0900

2つの日付の差を秒・分・時間などで出す

前述のnew Date同士の減算結果は2つの日付のミリ秒の差なので割ることによって差を秒・分・時間などに変換できる。

カウントダウンの残り時間の計算などに使用される。

var d1 = new Date('2019/01/01 00:00');
var d2 = new Date('2018/01/01 00:00');
var df = d1 - d2;

// ミリ秒 => 31536000000
console.log(df);

// 秒 => 31536000
console.log(df / 1000);

// 分 => 525600
console.log(df / 1000 / 60);

// 時間 => 8760
console.log(df / 1000 / 60 / 60);

// 日 => 365
console.log(df / 1000 / 60 / 60 / 24);

// 月 => 12
console.log(df / 1000 / 60 / 60 / 24 / (365 / 12));

// 年 => 1
console.log(df / 1000 / 60 / 60 / 24 / 365);

new Dateは日本にいても日本の日時を表示するとは限らない

new Dateは日本にいても言語設定が日本語以外になっているとブラウザによっては日本の日時を取得しないことがある。

例えばFirefoxの場合は以下のような結果にある。

// 言語設定が英語になっているFirefoxのnew Date()の結果
// 日本時間21:20に実行した結果
console.log(new Date());
// => Date 2017-04-10T12:20:17.638Z

午前・午後(AM・PM)や12時間表示にする

午前・午後(AM・PM)を取得するためのgetAMPM()のようなメソッドはないため、以下のように判定する。

12時間表示にしたい場合は午後の場合は12を引けば良い。

var h = new Date().getHours();
console.log(h < 12 ? '午前' : '午後');
// => 午前 or 午後

console.log(h < 12 ? `午前${h}時` : `午後${h - 12}時`);
// => 例: 午後3時

toLocaleString()で文字列化

toLocaleString()を使用すればnew Dateで作成した日付オブジェクトをロケールに対応した文字列で表示できる。

ただし、month, date, hourが1桁のときは頭の0は除外される。秒は省略していても:00が追加される。

日付または時刻だけを文字列化したい場合はtoLocaleDateString()およびtoLocaleTimeString()を使用する。

var d = new Date("2013/01/01 01:00");

console.log(d.toLocaleString());
// => 2013/1/1 1:00:00

console.log(d.toLocaleDateString());
// => 2013/1/1

console.log(d.toLocaleTimeString());
// => 1:00:00

toLocaleDateString('ja-JP-u-ca-japanese')で元号の年数に変換されるがブラウザによって挙動が異なる。(node.jsだと和暦を返さない)

さらに明治以前の年数は正しく取得できないので注意が必要。

var d = new Date("2013/01/01 01:00");

console.log(d.toLocaleDateString('ja-JP-u-ca-japanese'));
// Chromeの場合
// => 平成25/1/1

console.log(d.toLocaleDateString('ja-JP-u-ca-japanese'));
// Safariの場合
// => 25/1/1

年月日時分秒を簡単に加算

setYearやgetYearを使用すると年月日時分秒を簡単に加算することができる。もちろんマイナスにすれば減算も可能だ。

var d = new Date('2015/01/01 00:00:00');

d.setYear(d.getFullYear() + 10);
console.log(d.toLocaleString());
// => 2025/1/1 0:00:00

d.setMonth(d.getMonth() + 10);
console.log(d.toLocaleString());
// => 2025/11/1 0:00:00

d.setDate(d.getDate() + 10);
console.log(d.toLocaleString());
// => 2025/11/11 00:00:00

d.setHours(d.getHours() + 10);
console.log(d.toLocaleString());
// => 2025/11/11 10:00:00

d.setMinutes(d.getMinutes() + 10);
console.log(d.toLocaleString());
// => 2025/11/11 10:10:00

d.setSeconds(d.getSeconds() + 10);
console.log(d.toLocaleString());
// => 2025/11/11 10:10:10

Mathオブジェクトは数値に変換する

複数の日付の中から一番古いまたは一番新しい日付を検出する際はMath.minやMath.maxを使用するのだが、使用後は数値に変換されるため、元のDate型にするには再度new Date()で変換する必要がある。

var d1 = new Date('2018/01/01 00:00');
var d2 = new Date('2019/01/01 00:00');
var d3 = new Date('2017/01/01 00:00');
var min = Math.min(d1, d2, d3);
var max = Math.max(d1, d2, d3);

console.log(min);
// => 1483196400000

console.log(max);
// => 1546268400000

console.log(new Date(min));
// => Sun Jan 01 2017 00:00:00 GMT+0900 (JST)

console.log(new Date(max));
// => Tue Jan 01 2019 00:00:00 GMT+0900 (JST)

日付フォーマット用の関数

2020年7月24日 (金)のような形式で日付を表示したい場合は、日付フォーマット用の関数を作成しておくと便利だ。

可読性を考慮してテンプレート文字列を使用しているためBabel必須。

曜日を配列に入れているコードが多いが、下記のように文字列にしたほうがシンプルなのでおすすめ。

function formatDate(date) {
  const y = date.getFullYear()
  const m = date.getMonth() + 1
  const d = date.getDate();
  const day = '日月火水木金土'.charAt(date.getDay());
  return `${y}年${m}月${d}日 (${day})`;
}
const date = new Date('2020/07/24');
console.log(formatDate(date));
// => 2020年7月24日 (金)

月日の行頭に0を付ける場合は下記のようになる。

// ES5
('0' + (date.getMonth() + 1)).slice(-2);

// ES2017
String(date.getMonth() + 1).padStart(2, '0');

その他注意点

  • ○年○月○日のまま取得できないので漢字が含まれた日時は/(スラッシュ)に変換
  • getMonth()は月から1を引いた数(1月は0)で返すので1を加算する
  • 日付の加算および減算後の結果はうるう年も考慮される
  • Dateオブジェクトは1970年1月1日の前後273,785年を扱えるので紀元前の指定も可能。
  • getHours()やgetMinutes()は数値として時間を返すので1234のつもりが46にならないように先頭に空文字を付けるなどして文字列として結合するようにする。
var now1 = new Date("2014/01/01 12:34");
console.log(now1.getHours() + now1.getMinutes()) // 46

var now2 = new Date("2014/01/01 12:34");
console.log('' + now2.getHours() + now1.getMinutes()) // 1234

サーバーの時刻を取得する

new Date()はユーザーのデバイスの日時が取得されるためnew Date()だと都合が悪い場合がある。

サーバーの日時を取得するにはPHPやJavaなどサーバーサイドスクリプトが必要だと勘違いされることが多いがJavaScriptだけでもサーバーの日時を取得することは可能なので正確な日時を取得したい場合はサーバーから取得すると良い。

JavaScriptだけでもこちらの方法を使用すればサーバーの日時を取得することが可能だ。