テキスト・データ

UNIX時間(タイムスタンプ)の変換方法|秒・ミリ秒の見分け方と日本時間

UNIX時間(UNIXタイムスタンプ)は、「1970年1月1日0時0分0秒(UTC)から何秒たったか」を表す数値です。日時に直すには、この秒数を日・時・分・秒に分けて1970年1月1日に足します。日本時間で見たい場合は、さらに9時間を足します。たとえば「1700000000」は、UTCで2023年11月14日22時13分20秒、日本時間では2023年11月15日7時13分20秒です。

ログファイルやAPIの応答、データベースの中で「1700000000」や「1700000000000」のような数字を見かけたら、多くの場合これがUNIX時間です。10桁なら秒単位、13桁ならミリ秒単位と考えれば、ほとんどの場面で見分けられます。

この記事では、UNIX時間のしくみ、桁数での見分け方、タイムゾーンの考え方、手計算での変換、プログラムでの定番の書き方、2038年問題を順に取り上げます。数値をすぐ変換したいだけなら、タイムスタンプ変換ツールにUNIX時間を入力すると、日本時間(JST)とUTCの日付に変換できます。日付から逆にUNIX時間を求めることもできます。

UNIX時間とは:1970年1月1日0時(UTC)からの経過秒数

UNIX時間は、UNIX系のOSで時刻を扱うために使われてきた表し方です。現在は多くのプログラミング言語やデータベースで使われています。起点の「1970年1月1日0時0分0秒(UTC)」はエポックと呼ばれるため、UNIX時間は「エポック秒」とも呼ばれます。

UTC(協定世界時)は、世界の時刻の基準になる時刻です。日本時間(JST)はUTCより9時間進んでいます。

1日はちょうど86,400秒として数える

UNIX時間では、1日を必ず「24時間×60分×60秒=86,400秒」として数えます。実際の時刻にはまれに「うるう秒」が挿入されてきましたが、UNIX時間はうるう秒を数えません。そのため、UNIX時間を86,400で割れば、エポックから何日たったかがきれいに求められます。

数値だけで時刻を表すメリット

「2023/11/15 7:13:20」のような文字列は、国や環境によって書き方が違い、並べ替えや引き算もしにくい形式です。UNIX時間はただの整数なので、大小を比べれば時刻の前後がわかり、引き算すれば経過秒数が出ます。「2つのタイムスタンプの差が3,600なら1時間」という具合に扱えます。

10桁と13桁の見分け方:秒かミリ秒か

UNIX時間には、秒単位のものとミリ秒単位(1ミリ秒=1/1000秒)のものがあります。JavaScriptの Date.now() などはミリ秒を返します。UNIX系の date +%s コマンドは秒(整数)、Pythonの time.time() は秒(小数つき)を返します。現在の日時を表す値なら、桁数で次のように判断できます。

桁数 単位 例(同じ時刻) 主な使用場面
10桁 秒 1700000000 UNIX系のシステム、多くのAPI、PHP・Python
13桁 ミリ秒 1700000000000 JavaScript、Javaなど
16桁 マイクロ秒 1700000000000000 一部のデータベースやログ
19桁 ナノ秒 1700000000000000000 高精度な計測やログ

秒単位のUNIX時間が10桁になるのは、2001年9月9日(1,000,000,000秒)から2286年11月20日(9,999,999,999秒)までの期間です。今の日時を扱うかぎり、「10桁=秒」と考えて問題ありません。

単位を間違えたときに出る日付

単位を取り違えると、変換結果があり得ない日付になります。13桁の値を秒として変換すると数万年後の日付になり、10桁の値をミリ秒として変換すると1970年1月の日付になります。

例として、1700000000をミリ秒として読むと1,700,000秒です。1,700,000÷86,400=19日あまり58,400秒で、58,400秒=16時間13分20秒です。結果は「1970年1月20日16時13分20秒(UTC)」になります。

変換結果が1970年1月になったら、単位の取り違えを疑ってください。秒→ミリ秒は1000倍、ミリ秒→秒は1000で割って小数点以下を切り捨てます。

タイムスタンプ自体にはタイムゾーンがない

UNIX時間の数値は、どこの国で見ても同じ「その瞬間」を表します。東京とロンドンで同時にUNIX時間を取得すれば、同じ数値になります。タイムゾーンが関係するのは、その数値を人が読む日時に直すときだけです。

日本時間に直すときは9時間(32,400秒)を足す

日本時間はUTC+9です。日本では現在サマータイムを実施していないため、1年中UTCに9時間を足せば日本時間になります。秒に直すと9×3,600=32,400秒です。

  • UTCの日時 + 9時間 = 日本時間
  • 日本時間の日時 − 9時間 = UTC

変換した時刻がちょうど9時間ずれている場合は、ほぼ確実にUTCと日本時間の取り違えです。

日時からUNIX時間を求めるときはタイムゾーンを必ず決める

逆方向の変換では、元の日時がどのタイムゾーンのものかで結果が変わります。

  • 2024年1月1日0時(UTC)→ 1704067200
  • 2024年1月1日0時(日本時間)→ 1704067200 − 32400 = 1704034800

日本時間の0時は、UTCではまだ前日の15時です。そのため、日本時間で求めたUNIX時間のほうが32,400小さくなります。

プログラムで日時文字列を変換するときは、「+09:00」のようにUTCからの時差を明記すると取り違えを防げます。日時とUTCからの時差(オフセット)をまとめて書く形式は、RFC 3339(インターネット向けの日時表記の規格)で定められています。

手計算でUNIX時間を日時に変換する手順

電卓があれば、プログラムを使わなくても変換できます。1700000000を例に計算します。

  1. 86,400で割って日数を出す:1,700,000,000 ÷ 86,400 = 19,675.92…なので、エポックから19,675日たっています。
  2. 余りの秒数を出す:19,675 × 86,400 = 1,699,920,000。1,700,000,000 − 1,699,920,000 = 80,000秒です。
  3. 余りを時・分・秒に分ける:80,000 ÷ 3,600 = 22あまり800なので22時間。800 ÷ 60 = 13あまり20なので13分20秒。時刻は22:13:20です。
  4. 日数を年に分ける:1970年から2022年末までの53年間には、うるう年が13回(1972年〜2020年)あります。53 × 365 + 13 = 19,358日なので、2023年1月1日はエポックから19,358日後です。19,675 − 19,358 = 317日が残ります。
  5. 年内の日付を出す:2023年1月1日から317日後は、年初から数えて318日目です。1月〜10月の日数の合計は304日です(2023年はうるう年ではないので2月は28日)。318 − 304 = 14なので11月14日です。
  6. 日本時間に直す:2023年11月14日22:13:20(UTC)に9時間を足すと、翌日の2023年11月15日7:13:20(日本時間)になります。

基準点との差で計算すると速い

手順4・5の年の計算が面倒なら、日時がわかっている基準点との差で計算します。たとえば1704067200(2024年1月1日0時UTC)を基準に、1710000000を変換してみます。

  • 差:1,710,000,000 − 1,704,067,200 = 5,932,800秒
  • 5,932,800 ÷ 86,400 = 68あまり57,600秒、57,600秒 = 16時間
  • 2024年1月1日の68日後:1月31日+2月29日(2024年はうるう年)=60日なので、残り8日で3月9日
  • 結果:2024年3月9日16:00:00(UTC)=2024年3月10日1:00:00(日本時間)

日数の数え間違いが心配なときは、日付計算ツールで「1月1日の68日後」を確認できます。

代表的なUNIX時間と日時の対応表

確認用に、区切りのよい値を並べました。変換結果の検算に使えます。

UNIX時間(秒) UTC 日本時間(JST) 備考
0 1970-01-01 00:00:00 1970-01-01 09:00:00 エポック(起点)
86,400 1970-01-02 00:00:00 1970-01-02 09:00:00 ちょうど1日後
946,684,800 2000-01-01 00:00:00 2000-01-01 09:00:00 2000年の始まり(UTC)
1,000,000,000 2001-09-09 01:46:40 2001-09-09 10:46:40 10桁になった瞬間
1,234,567,890 2009-02-13 23:31:30 2009-02-14 08:31:30 数字の並びが話題になった値
1,700,000,000 2023-11-14 22:13:20 2023-11-15 07:13:20 本記事の計算例
1,704,067,200 2024-01-01 00:00:00 2024-01-01 09:00:00 2024年の始まり(UTC)
2,000,000,000 2033-05-18 03:33:20 2033-05-18 12:33:20 20億秒
2,147,483,647 2038-01-19 03:14:07 2038-01-19 12:14:07 符号付き32ビットの上限

JavaScript・Python・SQLでの定番の書き方

どの言語でも、確認すべき点は2つです。値がミリ秒か秒か、そして出力がUTCか日本時間かです。

JavaScript

JavaScriptの Date はミリ秒単位で動きます。秒単位のUNIX時間は1000倍してから渡します。

// 現在のUNIX時間
Date.now();                          // ミリ秒(13桁)
Math.floor(Date.now() / 1000);       // 秒(10桁)

// UNIX時間(秒)→ 日時
const d = new Date(1700000000 * 1000);
d.toISOString();                     // "2023-11-14T22:13:20.000Z"(UTC)
d.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' }); // 日本時間で表示

// 日本時間の日時 → UNIX時間(秒)
Date.parse('2024-01-01T00:00:00+09:00') / 1000;        // 1704034800

toLocaleString の表示形式は、実行環境によって多少変わります。また、「2024-01-01」のように日付だけの文字列はUTCとして解釈されます。一方、「2024-01-01T00:00:00」のように時刻つきでオフセットのない文字列は、実行環境のローカル時刻として解釈されます。詳しくはMDNのDateのリファレンスを参照してください。

Python

Pythonでは秒単位(小数つき)で扱います。タイムゾーンを明示するのが安全です。

import time
from datetime import datetime, timezone, timedelta

time.time()                       # 現在のUNIX時間(秒、小数つき)

JST = timezone(timedelta(hours=9))
datetime.fromtimestamp(1700000000, tz=timezone.utc)  # 2023-11-14 22:13:20+00:00
datetime.fromtimestamp(1700000000, tz=JST)           # 2023-11-15 07:13:20+09:00

datetime(2024, 1, 1, tzinfo=JST).timestamp()         # 1704034800.0

tz を指定せずに datetime.fromtimestamp() を使うと、実行しているPCのローカル時刻で表示されます。サーバーとPCでタイムゾーン設定が違うと結果が変わるため、指定しておくと確実です。

SQL(MySQL・PostgreSQL・SQLite)

データベースごとに関数が異なります。代表的な書き方は次のとおりです。

-- MySQL(結果はセッションのタイムゾーン設定で表示される)
SELECT FROM_UNIXTIME(1700000000);
SELECT UNIX_TIMESTAMP('2024-01-01 00:00:00');

-- PostgreSQL
SELECT to_timestamp(1700000000) AT TIME ZONE 'Asia/Tokyo';  -- 2023-11-15 07:13:20
SELECT EXTRACT(EPOCH FROM TIMESTAMPTZ '2024-01-01 00:00:00+09');  -- 1704034800(バージョンにより小数つきで表示)
SELECT EXTRACT(EPOCH FROM TIMESTAMPTZ '2024-01-01 00:00:00+09')::bigint;  -- 1704034800(整数)

-- SQLite(unixepoch修飾子の結果はUTC)
SELECT datetime(1700000000, 'unixepoch');               -- 2023-11-14 22:13:20
SELECT datetime(1700000000, 'unixepoch', '+9 hours');   -- 2023-11-15 07:13:20
SELECT strftime('%s', '2024-01-01 00:00:00');           -- 1704067200(UTCとして解釈)

MySQLの FROM_UNIXTIME と UNIX_TIMESTAMP は、接続ごとのタイムゾーン設定に従って日時を解釈・表示します。同じクエリでも、サーバーの設定によって9時間ずれることがあります。PostgreSQLの EXTRACT で整数が必要なときは、上の例のように ::bigint を付けて整数に変換します。

2038年問題とは:32ビットで表せる上限

2038年問題は、UNIX時間を符号付き32ビット整数で保存しているシステムで起きる問題です。符号付き32ビット整数で表せる最大値は2の31乗−1=2,147,483,647です。これは2038年1月19日3時14分7秒(UTC)、日本時間では同日12時14分7秒にあたります。

その1秒後には値があふれ(オーバーフロー)、最小値の−2,147,483,648に戻ります。この値は1901年12月13日20時45分52秒(UTC)を表すため、日付が突然100年以上前に戻ったように扱われます。期限の判定や日付の並べ替え、有効期限の計算などが誤動作するおそれがあります。

影響を受けやすい場所

64ビット整数で時刻を扱う環境では、上限は事実上問題にならないほど先です。一方、次のような場所には32ビットの制約が残っている可能性があります。

  • 古いOSや組み込み機器のファームウェア
  • 時刻を32ビット整数で保存するファイル形式や通信プロトコル
  • データベースの列を32ビットの INT 型で定義している場合
  • MySQLの TIMESTAMP 型(上限が2038年1月19日3時14分7秒UTC)

符号なし32ビット整数で保存していれば、上限は4,294,967,295(2106年2月7日6時28分15秒UTC)まで延びます。ただし、その場合は1970年より前の日時を表せません。

長期ローンの満期日や保証期限など、2038年以降の日付を扱うシステムでは、すでにこの上限にぶつかることがあります。使っている型を確認しておきましょう。

UNIX時間を変換するときのチェックリスト

変換結果がおかしいと感じたら、次の順に確認してください。

  • 桁数は何桁か:10桁なら秒、13桁ならミリ秒です。1970年1月の日付や数万年後の日付が出たら、単位の取り違えです。
  • ずれは9時間ちょうどか:UTCと日本時間の取り違えです。日本時間はUTC+9時間(+32,400秒)です。
  • 日時→UNIX時間のとき、タイムゾーンを指定したか:「+09:00」や tz= を明記すると、実行環境に左右されません。
  • 小数点がついていないか:Pythonの time.time() や、バージョンによってはPostgreSQLの EXTRACT(EPOCH ...) は小数つきで返します。整数部分が秒です。
  • 検算したか:0=1970-01-01 09:00(JST)、1700000000=2023-11-15 07:13:20(JST)など、表の値で確認できます。
  • 2038年以降の日付を扱うか:保存先の型が32ビット整数や、MySQLの TIMESTAMP 型になっていないか確認します。
やりたいこと 計算
秒 → ミリ秒 ×1000
ミリ秒 → 秒 ÷1000(小数点以下を切り捨て)
秒 → 日数 ÷86,400
UTC → 日本時間 +9時間(+32,400秒)
日本時間 → UTC −9時間(−32,400秒)

よくある質問

「エポック秒」「POSIX時間」とUNIX時間は同じものですか?

一般的には同じものを指します。どれも1970年1月1日0時0分0秒(UTC)を起点とし、うるう秒を数えない経過秒数です。資料によっては「epoch time」や「UNIXタイム」とも書かれます。ミリ秒単位の値を同じ名前で呼ぶこともあるため、桁数で単位を確認してください。

1970年より前の日時もUNIX時間で表せますか?

負の値を使えば表せます。たとえば−86,400は1969年12月31日0時(UTC)です。ただし、負のUNIX時間に対応していない関数やデータベースの型もあります。使う環境のドキュメントで、扱える範囲を確認してください。

ExcelでUNIX時間を日本時間に変換するにはどうすればいいですか?

Excelの日付は「1日=1」のシリアル値です。セルA1に秒単位のUNIX時間がある場合は「=A1/86400+DATE(1970,1,1)+9/24」と入力します。9/24は9時間分を足す処理で、結果のセルの表示形式を「yyyy/mm/dd hh:mm:ss」などの日付時刻に変えると日本時間で表示されます。13桁のミリ秒の場合は、86400ではなく86400000で割ります。

「1700000000.123」のような小数点つきのタイムスタンプは何を表していますか?

整数部分が秒、小数部分が1秒未満の端数です。1700000000.123なら、1700000000秒から0.123秒(123ミリ秒)後を表します。Pythonのtime.time()などはこの形式で返すため、秒単位の整数が必要なら小数点以下を切り捨てて使います。

現在のUNIX時間をすぐに調べる方法はありますか?

LinuxやmacOSのターミナルでは「date +%s」で、現在のUNIX時間を秒(整数)で表示できます。ブラウザの開発者ツールのコンソールで「Math.floor(Date.now()/1000)」を実行しても求められます。コマンドを使わない場合は、オンラインのタイムスタンプ変換ツールで現在時刻を確認する方法もあります。