UNIX 時刻 (UNIX タイム) は、1970 年 1 月 1 日 0 時 0 分 0 秒 (協定世界時、UTC) からの経過秒数で日時を表す方法です。PHP の time() など、多くの言語やデータベース、API で使われています。JavaScript でも同じ値を得たい場面はよくありますが、JavaScript の日時はミリ秒で数えるため、そのままでは 1,000 倍の値になります。ここでは、正しく秒を得る書き方と、よく見かける書き方の落とし穴を説明します。
秒で得るには Math.floor(Date.now() / 1000)
// 今の UNIX 時刻 (秒)
const now = Math.floor(Date.now() / 1000);
Date.now() は、1970 年 1 月 1 日 (UTC) からの経過ミリ秒を返します。これを 1,000 で割ると秒になりますが、小数が残るので Math.floor() で切り捨てます。
Date のオブジェクトがすでにあるなら、getTime() でミリ秒を取り出せます。
const date = new Date("2026-11-16T00:00:00+09:00");
const seconds = Math.floor(date.getTime() / 1000); // 1794754800
桁数を見ると、秒かミリ秒かの見当がつきます。今の日時なら、秒は 10 けた、ミリ秒は 13 けたです。API から受け取った値をそのまま new Date() に渡して 1970 年の日付になったら、秒とミリ秒を取り違えていないかを疑います。
ビット演算で切り捨てる書き方は 2038 年に壊れる
小数を切り捨てる短い書き方として、| 0 や ~~ が使われることがあります。
// 勧められない書き方
const now = (Date.now() / 1000) | 0;
ビット演算をすると、JavaScript は値をいったん 32 ビットの符号付き整数に変換します。32 ビットの符号付き整数で表せる最大の値は 2,147,483,647 です。UNIX 時刻がこの値を超えるのは、2038 年 1 月 19 日 3 時 14 分 7 秒 (UTC) の次の 1 秒です。それ以降は、値が負の数に変わってしまいます。
(2147483648.2) | 0; // -2147483648 (壊れている)
Math.floor(2147483648.2); // 2147483648 (正しい)
これは、UNIX 時刻を 32 ビットの符号付き整数で記録するシステムで起きる「2038 年問題」と同じ境目です。JavaScript の数値そのものは、もっと大きな値も正しく扱えるので、Math.floor() を使えばこの問題は起きません。有効期限のように未来の日時を扱う処理では、2038 年より先の値が出てくることも十分ありえます。
また、1970 年より前の日時は負の値になります。Math.floor() と Math.trunc() (0 の方向へ切り捨て) では負の値の扱いが違うので、どちらを使うかを決めてそろえておきます。
UNIX 時刻はタイムゾーンに左右されない
UNIX 時刻は「UTC の基準の瞬間から何秒たったか」なので、同じ瞬間なら、日本でもほかの国でも同じ値になります。端末のタイムゾーンの設定によって Date.now() の値が変わることはありません。
タイムゾーンが関わるのは、日時を文字にして表示するときと、文字の日時を読み取るときです。表示するときは、toLocaleString() でタイムゾーンを指定できます。
const date = new Date(1794754800 * 1000);
date.toLocaleString("ja-JP", { timeZone: "Asia/Tokyo" }); // "2026/11/16 0:00:00"
date.toLocaleString("ja-JP", { timeZone: "UTC" }); // "2026/11/15 15:00:00"
文字の日時を読み取るときは、時差を書いておくのが確実です。"2026-11-16" のように日付だけの文字列は UTC として、"2026-11-16T00:00" のように時刻があって時差が無い文字列は、端末のタイムゾーンとして読まれます。同じ日付でも結果が変わるので、+09:00 や Z (UTC) を付けて書きます。
UNIX 時刻から日時に戻す
秒の UNIX 時刻を Date に戻すときは、1,000 を掛けてミリ秒にしてから渡します。
const seconds = 1700000000;
const date = new Date(seconds * 1000);
date.toISOString(); // "2023-11-14T22:13:20.000Z"
toISOString() は、UTC の日時を決まった形式の文字列で返すので、記録やデータの受け渡しに向いています。
なお、Date.now() は利用者の端末の時計をもとにしているため、端末の時計がずれていれば値もずれます。有効期限の確認のように、正確さが必要な処理では、サーバー側の時刻を使います。
まとめ
- UNIX 時刻 (秒) は
Math.floor(Date.now() / 1000)で得る。Dateはミリ秒で数える | 0や~~での切り捨ては、32 ビットの範囲を超える 2038 年 1 月 19 日以降に壊れるので使わない- UNIX 時刻はタイムゾーンに依存しない。タイムゾーンが関わるのは表示と読み取りのとき
- 日時に戻すときは
new Date(秒 * 1000)と、ミリ秒にしてから渡す