0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UnixTimeをDBやAPIでどう扱う?日時保存・比較・変換でハマりやすいポイント

0
Posted at

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にする」

のではなく、

絶対的な時点なのか
カレンダー上の日付なのか
人間向けの日時なのか

を分けて考えると、後から扱いやすい設計になります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?