HB DevTools

Knowledge

Unixタイムスタンプとは?変換方法と開発現場での活用パターン

Unix時間(エポック秒)の概念、10桁と13桁の違い、タイムゾーン落とし穴、JavaScript・Python・SQL での変換方法、APIやデータベース設計での使い方を解説します。

Unixタイムスタンプバックエンド

1. Unixタイムスタンプとは

Unixタイムスタンプ(Unix time、エポック秒とも呼ばれます)は、1970年1月1日00:00:00 UTC(Unix元期)からの経過秒数を表す整数値です。 例えば 1700000000 は2023年11月14日22:13:20 UTCを表します。

タイムゾーンや夏時間(サマータイム)の影響を受けないため、 異なる地域・システム間で時刻情報を安全にやり取りできます。 データベースのレコード作成日時、APIのレスポンス、ログのタイムスタンプなど、 バックエンド開発のあらゆる場面で使われています。

Unixタイムスタンプと人間が読める日時の相互変換には、Unix Timestamp Converter が便利です。 10桁・13桁を自動判別し、ローカル時間とUTCを同時に表示します。

2. 10桁(秒)と13桁(ミリ秒)の違い

Unixタイムスタンプには秒単位(10桁)ミリ秒単位(13桁)の 2種類があります。両者の混在はバグの温床となるため、正確に区別することが重要です。

  • 10桁(秒単位): 例 1700000000(2023年現在の値は10桁)。 多くのデータベース(PostgreSQL, MySQL)やサーバーサイド言語の標準APIが 秒単位を返します。Cの time() 関数、Pythonの time.time()、 Rubyの Time.now.to_i などはすべて秒単位です。
  • 13桁(ミリ秒単位): 例 1700000000000。 JavaScriptの Date.now() やJavaの System.currentTimeMillis()、 多くのフロントエンドAPIはミリ秒単位を返します。 アニメーション・パフォーマンス計測など、1秒以下の精度が必要な場面で使われます。

バックエンドからミリ秒単位のタイムスタンプを受け取ってJavaScriptのnew Date(timestamp) に渡す場合はそのまま使えます。 逆に秒単位を渡すと1970年代の日時になってしまいます(×1000 の変換を忘れた場合)。 APIドキュメントに単位が明記されていない場合は、値の桁数で判断するか、 既知の日時(例:現在時刻に近い値かどうか)で確認します。

3. タイムゾーンの落とし穴

Unixタイムスタンプ自体はタイムゾーンを持ちませんが、 日時文字列との変換処理でタイムゾーンの扱いを誤ると、 意図しない時刻のずれが生じます。

JavaScriptの注意点new Date('2024-01-01') のように日付のみ(時刻なし)を渡すと、 ISO 8601の仕様に従いUTCの0時として解釈されます。 一方 new Date('2024-01-01T00:00:00') のようにT区切りで時刻を含めると、ローカルタイムゾーンの0時として解釈されます。 日本(UTC+9)では9時間のずれが生じ、2024-01-012023-12-31T15:00:00Z のタイムスタンプになってしまいます。

データベースとの一貫性: PostgreSQLの TIMESTAMP WITH TIME ZONEtimestamptz)型は 内部的にUTCで保存し、クエリ時にセッションのタイムゾーンに変換します。TIMESTAMP WITHOUT TIME ZONEtimestamp)型は タイムゾーン情報を持たず、挿入した値をそのまま返します。 アプリケーション側でタイムゾーン変換を行う設計か、 DBに任せる設計かを統一しないと、環境によって異なる値が返る原因になります。

推奨プラクティス: バックエンドとデータベースは常にUTCで時刻を扱い、 ユーザーへの表示時にのみローカルタイムゾーンへ変換する設計が最もシンプルで安全です。 Node.jsでは環境変数 TZ=UTC を設定し、 サーバーのシステムタイムゾーンに依存しない実装を心がけましょう。

4. 各言語での変換方法

よく使う言語でのUnixタイムスタンプと日時の相互変換をまとめます。

  • JavaScript: 現在時刻を秒単位で取得するには Math.floor(Date.now() / 1000)。 タイムスタンプ(秒)から Date オブジェクトへは new Date(timestamp * 1000)。 人間が読める形式への変換は date.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' }) またはIntl.DateTimeFormat を使います。
  • Python: 現在時刻は import time; time.time()(小数点付きの秒単位)。datetime モジュールではdatetime.fromtimestamp(ts, tz=timezone.utc) でUTC日時に変換できます。 タイムゾーン対応には pytz または Python 3.9以降の zoneinfo を使います。
  • SQL(PostgreSQL): タイムスタンプから変換は to_timestamp(1700000000)。 逆に日時からタイムスタンプは EXTRACT(EPOCH FROM now()) またはDATE_PART('epoch', now())::BIGINT です。
  • Gotime.Now().Unix() で秒単位、time.Now().UnixMilli() でミリ秒単位。 タイムスタンプから変換は time.Unix(ts, 0).UTC() です。

5. 開発現場での活用場面

  • JWT(JSON Web Token)の有効期限: JWTの exp(有効期限)・iat(発行日時)クレームは Unixタイムスタンプ(秒単位)で表現されます。 トークンのデバッグ時に有効期限の確認で変換ツールが活躍します。
  • ログの解析: 多くのサーバーログやクラウドサービスのログは Unixタイムスタンプで時刻を記録します。 特定の時刻に発生したエラーを調査する際に、 ログのタイムスタンプと実際の時刻の対応を確認するのに使います。
  • キャッシュの有効期限管理: HTTPの Cache-Control ヘッダーの max-age や RedisのEXPIREコマンドでは、 現在時刻からの相対秒数で有効期限を指定します。 Unixタイムスタンプで絶対時刻を計算してから差分を求めるパターンもよく使われます。
  • 2038年問題: 32ビット符号付き整数でUnixタイムスタンプを格納しているシステムでは、 2038年1月19日(2147483647)にオーバーフローが発生します。 レガシーシステムのメンテナンス時に確認が必要な点です。 現代の64ビット整数では実質的な問題はありません。

6. 実務Tips

  • 相対時間の表示: 「3分前」「昨日」のような相対時間表示には、Intl.RelativeTimeFormat(ブラウザ標準API)が使えます。 現在時刻との差分を計算してから渡します。 より多機能な実装が必要なら date-fnsformatDistanceToNow が便利です。
  • デバッグ時の確認: APIレスポンスのタイムスタンプが正しいかどうかを素早く確認したいとき、Unix Timestamp Converter に 貼り付けると、ローカル時間とUTCで即座に確認できます。 桁数も自動判別するため、秒・ミリ秒の区別を意識せずに使えます。
  • 将来の日時を計算する: 「30日後の0時」のようなタイムスタンプを計算する場合、 単純に now + 30 * 24 * 60 * 60 とすると夏時間のある地域で1時間ずれます。date-fnsaddDaysdayjs など ライブラリを使うと夏時間・うるう秒を考慮した正確な計算ができます。