Webアプリを作っていると、日時データをどう保存するかで迷うことがあります。
たとえば、
2026-09-01 14:30:00
のような日時文字列で保存する方法もあれば、
1788240600
のようなUnixTimeで扱う方法もあります。
どちらも「日時」を表していますが、用途によって向き・不向きがあります。
特に、
- APIで日時を渡す
- DBに作成日時を保存する
- 有効期限を判定する
- ログを並べ替える
- 経過時間を計算する
といった処理では、UnixTimeを使うと実装がシンプルになることがあります。
この記事では、UnixTimeを実際の開発でどう扱うかを整理します。
UnixTimeは「日時」ではなく経過時間
UnixTimeは、
1970-01-01 00:00:00 UTC
から何秒経過したかを表す数値です。
そのため、
2026-09-01 14:30
のような人間向けの表記とは考え方が違います。
UnixTimeでは基本的に、
過去 → 小さい値
未来 → 大きい値
になります。
この特徴によって、日時の比較が非常に簡単になります。
有効期限の判定が簡単
たとえば、APIトークンの有効期限を判定するとします。
現在時刻が、
1788240000
有効期限が、
1788243600
なら、
if (currentTimestamp < expiresAt) {
console.log("有効");
} else {
console.log("期限切れ");
}
のように、単純な数値比較で判定できます。
日時文字列を毎回パースする必要がありません。
経過時間も引き算だけで求められる
UnixTime同士なら、
終了時刻 - 開始時刻
で経過秒数を求められます。
たとえば、
const startedAt = 1788240000;
const finishedAt = 1788240120;
const elapsed = finishedAt - startedAt;
console.log(elapsed);
// 120
結果は120秒です。
分へ直すなら、
console.log(elapsed / 60);
// 2
となります。
処理時間やセッション時間、キャッシュ期限などを扱うときに便利です。
JavaScriptではミリ秒になる点に注意
JavaScriptでUnixTimeを扱う場合は、単位に注意が必要です。
Date.now()はミリ秒単位です。
console.log(Date.now());
たとえば、
1788240600123
のような値になります。
一般的な秒単位のUnixTimeへ直すなら、
const timestamp = Math.floor(Date.now() / 1000);
console.log(timestamp);
とします。
逆に、秒単位のUnixTimeからDateを作る場合は1000倍します。
const timestamp = 1788240600;
const date = new Date(timestamp * 1000);
この1000倍・1000分の1を忘れると、まったく違う日時になるので注意が必要です。
APIでは単位を明示した方が安全
APIで、
{
"created_at": 1788240600
}
のようなデータを返した場合、
これが、
秒
なのか、
ミリ秒
なのか、値だけでは仕様が分かりません。
そこで、
{
"created_at_unix": 1788240600
}
としたり、API仕様書に、
Unix timestamp in seconds
と明記した方が安全です。
さらに明確にするなら、
{
"created_at": "2026-09-01T05:30:00Z"
}
のようにISO 8601を使う方法もあります。
UnixTimeとISO 8601はどちらがいい?
これは用途によります。
UnixTime:
1788240600
ISO 8601:
2026-09-01T05:30:00Z
UnixTimeは数値なので、
- 比較
- 計算
- ソート
- 有効期限判定
が分かりやすいです。
一方、ISO 8601は人間が見ても日時を判断しやすいというメリットがあります。
APIではISO 8601を使い、内部処理ではUnixTimeへ変換する設計もよくあります。
DBでは何を保存するべき?
データベースで日時を保存するとき、
UnixTimeを整数として保存する
方法と、
TIMESTAMP / DATETIME型を使う
方法があります。
UnixTimeなら、
1788240600
のような整数です。
たとえば概念的には、
created_at BIGINT
のように保存できます。
一方、RDBの日時型なら、
created_at TIMESTAMP
のようにできます。
どちらが必ず正解というわけではありません。
UnixTime保存のメリット
UnixTimeを整数で保存すると、
数値として扱いやすいというメリットがあります。
たとえば、
SELECT *
FROM sessions
WHERE expires_at < 1788240600;
のように期限切れデータを探せます。
また、言語が違っても同じ数値として受け渡しやすい点も便利です。
日時型を使うメリット
一方、DBの日時型を使えば、
SELECT *
FROM users
WHERE created_at >= '2026-09-01 00:00:00';
のように、人間にも比較的読みやすいSQLになります。
DB側の日時関数も利用できます。
たとえば日ごとの集計や月単位の検索では、日時型の方が扱いやすい場合があります。
そのため、
UnixTimeだから常に優れている
というわけではありません。
用途に合わせて選ぶ必要があります。
UTCで保存して表示時に変換する
日時処理で重要なのは、
保存する時刻
と、
表示する時刻
を分けることです。
日本向けサービスだからといって、すべてのデータをJST前提で保存すると、将来海外対応したときに扱いづらくなる場合があります。
一般的には、
内部ではUTC
↓
表示するときにユーザーのタイムゾーンへ変換
という設計が分かりやすいです。
UnixTimeは絶対的な時点を数値として扱うため、この考え方と相性が良いです。
「今日のデータ」を取得するときは注意
UnixTimeを使っていると、
今日の0:00から23:59まで
という検索が少しややこしくなることがあります。
「今日」はタイムゾーンによって違うからです。
たとえば日本時間の、
2026-09-01 00:00 JST
とUTCの、
2026-09-01 00:00 UTC
は同じ瞬間ではありません。
そのため、
どのタイムゾーンにおける今日なのか
を決めてからUnixTimeへ変換する必要があります。
日付だけ保存したい場合はUnixTimeが最適とは限らない
たとえば誕生日、
2000-05-10
を保存するとします。
これは「世界中で共通の瞬間」を表したいわけではありません。
単純に、
5月10日
という日付そのものが重要です。
このようなデータを無理にUnixTimeへ変換すると、タイムゾーンによって日付がずれる原因になります。
誕生日や締切日など、
時刻を必要としない日付
はDATE型などで保存した方が分かりやすいことがあります。
2038年問題とは?
UnixTimeについて調べると「2038年問題」という言葉を見ることがあります。
32bitの符号付き整数でUnixTimeを扱う場合、最大値は、
2,147,483,647
です。
これは、
2038-01-19 03:14:07 UTC
付近に相当します。
これを超えると32bit signed integerでは表現できなくなります。
現在の多くの環境では64bit対応が進んでいますが、古いシステムや組み込み環境などでは確認が必要です。
DBでUnixTimeを整数保存する場合も、将来の日付を扱うなら型の範囲を意識しておく必要があります。
UnixTimeは1970年より前も扱える
Unix epochより前の日時は、負のUnixTimeとして表すことができます。
たとえば、
1969-12-31 23:59:59 UTC
なら、
-1
です。
ただし、言語やライブラリ、OSによって過去の日時の扱いに差が出る場合があります。
歴史的な日時データまで扱うシステムでは注意が必要です。
Timestampの確認には変換ツールが便利
APIレスポンスやログに、
1788240600
のような値が出てきたとき、
「これは何日の何時?」
とすぐ確認したいことがあります。
その場合は、UnixTimeと通常日時を変換して確認すると分かりやすいです。
特にAPIやログのデバッグでは、Timestampを人間が読める日時へ変換して確認する機会がよくあります。
JavaScriptで簡単な変換関数を作る
UnixTimeから日時へ変換するなら、
function unixToDate(timestamp) {
return new Date(timestamp * 1000);
}
console.log(unixToDate(1788240600));
逆にDateから秒単位のUnixTimeへ変換するなら、
function dateToUnix(date) {
return Math.floor(date.getTime() / 1000);
}
console.log(dateToUnix(new Date()));
とできます。
API設計では形式を統一する
システムが大きくなると、
API A:
秒
API B:
ミリ秒
API C:
ISO 8601
という状態になることがあります。
こうなると、変換処理が増えてバグの原因になります。
できるだけ、
外部APIではISO 8601
または、
UnixTimeなら必ず秒
のようにルールを統一した方が安全です。
変数名も、
createdAtUnixSeconds
createdAtMilliseconds
のように単位が分かる名前にすると、さらに事故を減らせます。
UnixTimeが向いている処理
UnixTimeは特に、
- 有効期限
- セッション期限
- キャッシュ期限
- ログ
- 処理開始・終了時刻
- 経過時間
- 時系列ソート
のような処理と相性が良いです。
単純な数値なので、
比較
加算
減算
がしやすいからです。
UnixTimeを使わない方が分かりやすい場合
逆に、
- 誕生日
- 記念日
- 月日だけのデータ
- 営業日
- カレンダー上の日付
などは、必ずしもUnixTimeにする必要はありません。
重要なのは、
そのデータが「瞬間」を表しているのか
「日付」を表しているのか
を区別することです。
まとめ
UnixTimeは、
1970-01-01 00:00:00 UTC
からの経過時間を数値として表す仕組みです。
数値なので、
日時比較
期限判定
経過時間計算
ソート
などに向いています。
一方で、
タイムゾーン
秒・ミリ秒
2038年問題
日付だけのデータ
など、注意するポイントもあります。
日時処理を設計するときは、
「とりあえず全部UnixTimeにする」
のではなく、
絶対的な時点なのか
カレンダー上の日付なのか
人間向けの日時なのか
を分けて考えると、後から扱いやすい設計になります。