Unixタイムスタンプ説明:秒、ミリ秒、タイムゾーンと2038
Unixタイムとは何かシステムでなぜ使うのかタイムスタンプを各言語で変換する方法時間帯やミリ秒やY2038のバグを回避する方法
· 7 分で読めます
Open almost any log file、database table or API response and you will find numbers like 1760000000。1970年1月1日の00:00:00 UTC以降の秒数です。Unix時代として知られています。コンピュータが時間の瞬間を表現する最も一般的な方法であり、それを理解することでタイムゾーン、夏令和、日付解析などのバグを防ぐことができます。
なぜ1970年から秒を数えるの?
初期のUnix開発者はシンプルでコンパクトな時間の表現が必要でした。固定された最近の日付から秒数を数えるのは 1 つの整数に適合し、比較し減算することが容易で、カレンダーの複雑さを回避しました。1970年1月1日という日付は Unixが作られるときの簡単なスタート地点でした
利点は今日も残っています
- *タイムゾーン独立。 * タイムスタンプはウォールクロックではなく瞬間の識別です。同じイベントは東京、ベルリン、サンパウロでも同じタイムスタンプがあります
- 2つのタイムスタンプの差は秒で表示される時間です。1日あたり 86,400 歩前進します
- **コンパクトでソートできる.**整数には8バイトがあり、時間順にソートする。
- 曖昧さなく 3月4日と4月3日との間には混同はありません
秒対ミリ秒
タイムスタンプのバグは単位を混ぜるものです
- Unix ツール、ほとんどのデータベース、JWT、多くの API は、現在
1760000000のように 10 桁の 秒 を使用しています。 - JavaScriptの
Date.now()、JavaのSystem.currentTimeMillis()と多くの分析システムは、1760000000000のような13桁のミリ秒を使用しています。 - システムによってはマイクロ秒 (16桁) やナノ秒 (19桁) が使われます
ミリ秒を秒で解釈すると数万年後の日付が得られます逆転すると 1970年1月にたどり着きます。1970年11月21日という数字がユーザーインタフェースに表示された場合予想されていたミリ秒が秒過ぎたということです。[タイムスタンプ変換] ((/ツール/タイムスタンプ) は長さで単位を検出し、迅速な精神的チェックです。
タイムスタンプを共通言語に変換する
JavaScript
const nowSeconds = Math.floor(Date.now() / 1000);
const date = new Date(1760000000 * 1000);
date.toISOString(); // "2025-10-09T08:53:20.000Z"
パイソン
import time, datetime
now = int(time.time())
dt = datetime.datetime.fromtimestamp(1760000000, tz=datetime.timezone.utc)
Pythonでは常に tz= を渡します.それなしでは、fromtimestamp は誤解しやすい無知なローカル時間を返します。
**SQL (PostgreSQL) **
SELECT to_timestamp(1760000000); -- timestamptz
SELECT extract(epoch FROM now())::bigint; -- current Unix time
ほら行け
t := time.Unix(1760000000, 0).UTC()
now := time.Now().Unix()
シェル
date +%s # current timestamp
date -u -d @1760000000 # GNU date
date -u -r 1760000000 # macOS/BSD date
時間帯: UTC を保存、現地表示
タイムスタンプには時間帯がありません絶対的な瞬間です。人間が読み取れる日付に変換する際に問題が発生します。
- ゾーンなしの日付をパースする。
new Date("2026-03-29 02:30")は、コードを実行する機械のローカルタイムゾーンで解釈されます。UTCのサーバーとベルリンのラップトップで異なるタイムスタンプを生成します - 夏令間の差と重複. 昼間時間帯では、一部の地方時間は存在しない (時計は前方に跳ね上がる) と、他の時間は2回発生する (時計は後方に戻る)。タイムスタンプにはそんな曖昧さはない
- "2026-11-01 01:30"をゾーンなしで保存すると、どの瞬間だったかは分からない。
原則として、タイムスタンプやISO 8601文字列を明示的なオフセット (2026-10-11T09:30:00Zまたは+02:00) で保存し送信します。ユーザのローカルゾーンに変換する。ユーザの IANA 時間帯名 (Europe/Berlin など) を、その地域の時間でスケジュールする必要がある場合、別々に保存します。
ISO 8601 と Unix のタイムスタンプ
2026-10-11T09:30:00ZのようなISO 8601文字列は、Zまたはオフセットを含むとき、人間に読み取れるし、曖昧ではない。多くのAPIは読みやすくするためにそれらを好みます。Unixのタイムスタンプは小さく比較が速く。両方とも大丈夫です重要なのは一貫性ですゾーン情報を常に含めることです
スキット秒
地球の回転は少し不規則なので公式のUTCは時々うるう秒を入れます。Unixの時間はそれらを無視します毎日が正確に 86,400 秒で、うるう秒間にタイムスタンプが繰り返され、または抹消されます。ほとんどすべてのアプリケーションではこれは目に見えないものです。高精度なタイミングで作業する場合は TAI または GPS 時間を使います。国際時間計測機関が 2035年までに飛秒を廃止することを決定しましたこれによって懸念が減ります
2038年の問題
多くの古いシステムでは、Unix時間を署名された32ビット整数として保存し、その最大値は2,147,483,647である。これは2038年1月19日の 03:14:07 UTC に対応しています。1秒後、値は−2,147,483,648に溢れ、これは1901年12月13日を表しています。
現代の64ビットオペレーティングシステム、言語、データベースは64ビットタイムスタンプを使用し、約2920億年以内に溢れません。リスクは以下にあります。
- 長寿命のインベテッドデバイスと産業用コントローラ
- ファイル形式と32ビットタイムフィールドのネットワークプロトコル
- データベース列は32ビット
INTで宣言され、エポック秒を保持する。MySQL のTIMESTAMP型には 2038 の制限がありますが、DATETIMEやBIGINTはありません。
証明書の有効期限や20年契約などの将来の日付を保存するものをチェックしてください
ネガティブなタイムスタンプ
1970年以前の日付には負のタイムスタンプがあります。-86400は1969年12月31日。現代の言語の大半は正しく処理していますが古いAPIやスプレッドシートはそうではありませんので明らかに歴史日付をテストしてください
実用的なデバッグチェックリスト
- 数字を数える 10 は秒で 13 はミリ秒
- 単位バグとゾーンバグを分離するために、まずUTCに変換し、その後ローカルタイムに変換します。
- 解析する前に、日付文字列に
Zまたはオフセットが含まれているか確認します。 - トークンや署名が"有効期限切れ"または"まだ有効ではない"エラーで失敗した場合、サーバーとクライアントのクロックを比較します。
expとnbfが Unix 秒である理由については、[JWT の動作方法] ((/blog/how-jwt-works) を参照してください。 - 繰り返されるタスクをスケジュールする際には、cronがサーバーのゾーンで実行されることを忘れないでください。[これらのcron例] (/blog/cron-expression-examples) は詳細をカバーします。
まとめ
Unixタイムスタンプは,1970-01-01 UTC以降の秒数である。シンプルでタイムゾーン独立で計算が簡単です。ほとんどのバグは秒とミリ秒を混ぜたりゾーンなしの日付を解析したり地元の時間を保存したりで発生します。64ビット整数を使えば時間について考える必要がなくなるでしょう
このページは英語から自動翻訳されています。誤りを見つけた場合はお知らせください。