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を例に計算します。
- 86,400で割って日数を出す:1,700,000,000 ÷ 86,400 = 19,675.92…なので、エポックから19,675日たっています。
- 余りの秒数を出す:19,675 × 86,400 = 1,699,920,000。1,700,000,000 − 1,699,920,000 = 80,000秒です。
- 余りを時・分・秒に分ける:80,000 ÷ 3,600 = 22あまり800なので22時間。800 ÷ 60 = 13あまり20なので13分20秒。時刻は22:13:20です。
- 日数を年に分ける:1970年から2022年末までの53年間には、うるう年が13回(1972年〜2020年)あります。53 × 365 + 13 = 19,358日なので、2023年1月1日はエポックから19,358日後です。19,675 − 19,358 = 317日が残ります。
- 年内の日付を出す:2023年1月1日から317日後は、年初から数えて318日目です。1月〜10月の日数の合計は304日です(2023年はうるう年ではないので2月は28日)。318 − 304 = 14なので11月14日です。
- 日本時間に直す: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)」を実行しても求められます。コマンドを使わない場合は、オンラインのタイムスタンプ変換ツールで現在時刻を確認する方法もあります。