時刻形式を変換する方法
時刻形式はシステム、API、国の間で変動します。APIレスポンスのUnixタイムスタンプ、データベースのISO 8601、米国の12時間時計、ヨーロッパの24時間時計など、それらの間の変換は開発者と国際データを扱うあらゆる人にとって絶え間ない必要です。各形式が存在する理由、どこで輝き、どこで噛みつくかを理解することで、変換は微妙なバグの繰り返しの原因ではなく、素早い反射になります。
時刻形式の簡単な歴史
時刻の標準化はインターネットより古いです。1884年に国際子午線会議がグリニッジ標準時と本初子午線を確立し、世界に初めて共通の参照を与えました。24時間時計は同じ理由で航空と軍を通じて広まりました。真夜中の予約を昼の便に変えるAM/PMの曖昧さを取り除くからです。
Unix時間は1971年の元のUnixカーネルとともに到来し、1970年1月1日UTC(「エポック」)からの秒数を数えました。選択は実用的でした。32ビット整数は数十年をカバーでき、タイムスタンプのソートは数値のソートを意味し、間隔の計算は減算でした。ISO 8601は1988年に人間が読める側を標準化するために登場しました。ビッグエンディアン順の年月日、日付/時刻区切りとしてのT、UTCのためのZ。RFC 3339(2002年)はインターネットプロトコル用に設計されたISO 8601のより制限的なプロファイルです。RFC 2822(2001年)は曜日名とオフセット付きのメールスタイル形式を定義します。各形式は実際の問題を解決します。どれも他を完全に置き換えることはありません。
一般的な時刻形式
6つの形式が、現実世界で遭遇するほぼすべてをカバーします。最初の列はドキュメントで見る名前、例の列は2024年4月7日UTCの14:30の見え方を示します。
| 形式 | 例 | 使われる場所 |
|---|---|---|
| Unixタイムスタンプ(秒) | 1712502600 | API、データベース、JWTトークン、ログ行 |
| Unixタイムスタンプ(ms) | 1712502600000 | JavaScript、Java、Android |
| Unixタイムスタンプ(マイクロ秒) | 1712502600000000 | Postgres、Kafka、OpenTelemetry |
| ISO 8601 / RFC 3339 | 2024-04-07T14:30:00Z | JSON API、データベース、ログ |
| RFC 2822 | Sun, 07 Apr 2024 14:30:00 +0000 | メールヘッダー、HTTPヘッダー |
| 24時間 | 14:30 | ヨーロッパ、軍、航空 |
| 12時間 | 2:30 PM | 米国、カジュアル用途 |
| 年間日(ユリウス) | 2024-098 | 航空電子機器、科学データ |
| 週日付 | 2024-W14-7 | 産業計画、銀行 |
ほとんどのチームは保存用にUnixミリ秒、転送用にISO 8601で落ち着き、表示形式はロケールごとに選びます。選択は一貫性より重要ではありません。プライマリ形式を選び、文書化し、エッジで変換します。
素早い変換リファレンス
12時間から24時間
12時間時計には2つの奇妙さがあります。12 AMは真夜中(1日の始まり)で、12 PMは正午です。下の表は人々がつまずくケースをカバーします。
| 12時間 | 24時間 |
|---|---|
| 12:00 AM(真夜中) | 00:00 |
| 1:00 AM | 01:00 |
| 11:59 AM | 11:59 |
| 12:00 PM(正午) | 12:00 |
| 12:01 PM | 12:01 |
| 1:00 PM | 13:00 |
| 6:00 PM | 18:00 |
| 11:59 PM | 23:59 |
タイムスタンプから日付へ
エポックコンバーターは、Unixタイムスタンプを人間が読める日付に、またその逆に瞬時に翻訳します。コンバーターは秒(10桁)とミリ秒(13桁)の両方を自動検出するため、単位を心配せずに任意のソースから値を貼り付けられます。
有用な健全性チェック: 86400(1日の秒数)で割り、1970年に日数を加えて、任意のタイムスタンプを精神的に特定します。1712502600 / 86400 ~ 19820日、これは1970年から約54年で、2024年に位置づけます。精密ではありませんが、一目で1000倍ずれエラーをキャッチするのに十分です。
コードでの変換例
ほとんどの開発者は最終的にコードでタイムスタンプを変換する必要があります。コアAPIは短いです:
- JavaScript:
new Date(1712502600 * 1000).toISOString()は2024-04-07T14:30:00.000Zを返します。JavaScriptのDateはミリ秒を期待するため、1000を掛けることを覚えておいてください。逆方向はMath.floor(Date.now() / 1000)が秒タイムスタンプを返します。 - Python:
datetime.fromtimestamp(1712502600, tz=timezone.utc).isoformat()は2024-04-07T14:30:00+00:00を返します。utcfromtimestamp()は避けてください。残りのコードが誤ってローカル時刻として扱う、ナイーブなdatetimeを返します。 - Go:
time.Unix(1712502600, 0).UTC().Format(time.RFC3339)は2024-04-07T14:30:00Zを返します。Goのtimeパッケージは独特ですが、参照レイアウトMon Jan 2 15:04:05 MST 2006を内在化すれば一貫しています。 - シェル: GNU / Linuxでは
date -u -d @1712502600 +"%Y-%m-%dT%H:%M:%SZ"、BSD / macOSではdate -u -r 1712502600 +"%Y-%m-%dT%H:%M:%SZ"。フラグの違いは、最もGoogleされるクロスプラットフォームの罠の1つです。 - Rust:
chrono::DateTime::<chrono::Utc>::from_timestamp(1712502600, 0).unwrap().to_rfc3339()は同じISO文字列を返します。標準ライブラリには現在SystemTimeがありますが、chronoはフォーマットに対してまだ実用的な選択です。 - SQL(Postgres):
SELECT to_timestamp(1712502600) AT TIME ZONE 'UTC';はtimestamptzを返します。MySQLはFROM_UNIXTIME()を、SQLiteはdatetime(1712502600, 'unixepoch')を使います。
これらの1行コマンドのどれよりも、コンバーターツールが単一の値を翻訳するだけのときには速く、それがデバッグ中のほとんどの時間です。
ISO 8601が保存で勝つ理由
ISO 8601(およびそのRFC 3339プロファイル)は、プレーン文字列として正しくソートされます。2024-04-07T14:30:00Zは2024-04-07T15:00:00Zのアルファベット順前にあり、それは2024-04-08T00:00:00Zの前にあります。その特性により、解析せずにタイムスタンプをソートでき、sort | uniq -cでログ行をグループ化でき、シンプルな文字列比較で範囲について推論できます。
また、地域形式が曖昧でないのとは違って曖昧でもありません。04/07/2024は4月7日(米国)または7月4日(ヨーロッパのほとんど)である可能性がありますが、2024-04-07はすべてのロケールで同じです。マシン間交換において、その曖昧さのなさは他のどのフォーマット考慮事項よりも価値があります。
避けるべきよくある落とし穴
- タイムゾーンを忘れる:
2026-04-07 14:30はゾーンなしでは曖昧です。ISO文字列を保存するときはつねにZまたは+00:00オフセットを含め、読者のデフォルトゾーンに決して依存しないでください。 - 秒とミリ秒の混同: 10桁のUnixタイムスタンプは秒、13桁はミリ秒です。それらを混ぜると、1970年または遠い未来のどちらかの日付を生成します。マイクロ秒(16桁)とナノ秒(19桁)も忍び寄っているので、それらも予期してください。
- サーバーでローカル時刻に依存する: サーバーがUTCで、ユーザーが東京にいる場合、UTCを保存して表示で変換します。サーバーにロケールを推測させると、ユーザーが旅行したり夏時間が変更されたりするときにほぼ常にバグが起こります。
- 文字列演算でパースする: 日付文字列を切り取って連結しないでください。
Date.parse()、dateutil.parser、chrono、または言語の標準ライブラリを使ってください。手動パースは極端な日付、うるう年、タイムゾーンオフセットで壊れます。 new Date("2024-04-07")を信頼する: JavaScriptは日付のみの文字列をUTC真夜中としてパースしますが、ゾーンなしの日付時刻文字列はローカル真夜中としてパースします。動作はブラウザとNodeバージョン間で異なります。つねに明示的なZまたはオフセットを含めてください。- 2桁の年:
04/07/24は実装に応じて1924年、2024年、または2124年である可能性があります。どこでも4桁の年を使ってください。 - 夏時間の遷移: ローカルクロックは春に1時間スキップし、秋に1時間繰り返します。素朴なスケジューラはそれらの日にジョブを2回実行するか、まったく実行しないかもしれません。スケジューリングロジックにはUTCを使い、表示のためだけに変換します。
- うるう秒: Unix時間は、影響を受ける秒をスメアまたは繰り返すことで存在しないかのように扱います。「経過秒」を比較するコードは、うるう秒を尊重する壁時計と一時的に意見が合わなくなる可能性があります。
- 2038年問題: 32ビット符号付き
time_tは2038年1月19日にオーバーフローします。ほとんどのモダンシステムは64ビット時間を使いますが、レガシー組み込みデバイスと古いデータベース列はまだそれに当たる可能性があります。タイムスタンプを保存するためにINT4やint32が使われている場所を監査してください。 - ロケール依存のフォーマット: JavaScriptの
toLocaleString()や他言語の同等関数は、マシンごとに異なる出力を生成します。マシン可読のタイムスタンプにはtoISOString()またはその同等物を、表示には明示的にフォーマットしてください。
代替ツールとライブラリ
コンバーターは一度限りのケースを処理しますが、本番コードにはライブラリに手を伸ばします。
| ツール / ライブラリ | 言語 | 強み | 注意点 |
|---|---|---|---|
| Webコンバーター | ブラウザ | 瞬時、インストール不要、よくある曖昧さを処理 | 一度に1つの値 |
dateutil | Python | 寛容なパーサー、タイムゾーン対応 | バルク作業でdatetimeより遅い |
arrow | Python | フレンドリーなAPI、ISOデフォルト | 小さなプロジェクトには余分な依存 |
date-fns | JavaScript | ツリーシェイク可能、不変 | 各関数が独自のインポート |
dayjs | JavaScript | 小さい、moment互換のAPI | 追加機能のためのプラグインモデル |
luxon | JavaScript | ファーストクラスのIANAタイムゾーン | より大きなバンドル |
chrono | Rust | 豊富な型、RFC 3339ネイティブ | メンテナンスペースが変動 |
Joda-Time / java.time | Java | 他に影響を与えた参照設計 | レガシーのDateとCalendarを避ける |
NodaTime | C# / .NET | 瞬間、期間、カレンダーがクリーンに分離 | DateTimeからの移行は非自明 |
GNU date | Linuxシェル | -dで柔軟なパース | BSD / macOSは互換性のないフラグを使う |
正しいライブラリはスタックに依存します。正しい規律はどこでも同じです。UTCを保存し、ISO 8601を送信し、表示のためだけにフォーマットし、明示的なゾーンなしのタイムスタンプを決して信頼しないでください。
プライバシーとコンバーター
時刻形式コンバーターは完全にブラウザ内で動作します。貼り付けたタイムスタンプと生成した日付はページを離れません。どの値が変換されたかのサーバーログも、どの形式が人気かの分析も、リクエストをIPにリンクする方法もありません。時刻変換自体は個人データではありませんが、ログのタイムスタンプ(ログイン時刻、トランザクション時刻、スケジュールウィンドウ)はしばしばそうであり、それらを第三者のコンバーターに送ると運用詳細が漏れる可能性があります。クライアントサイドで作業することで、その情報はあるべきマシン上に保たれます。秒とISO 8601の間の切り替えのような日常的なタスクには、プライバシーのデフォルトは、送信なし、ロギングなし、ループ内の第三者なし、であるべきです。
よくある質問
ISO 8601 形式とは何ですか?
ISO 8601 は日付と時刻を表す国際標準です。2026-04-07T14:30:00Z のような形をしており、T が日付と時刻を区切り、Z が UTC を示します。ロケールに関係なく曖昧さがありません。
なぜ API は人間が読める日付ではなく Unix タイムスタンプを使うのですか?
Unix タイムスタンプは単一の数値で、保存、ソート、比較が簡単です。タイムゾーンに依存せず(常に UTC)、書式付きの日付文字列より省スペースです。トレードオフは、人間にとって読みづらいことです。
タイムスタンプの末尾の Z は何を意味しますか?
Z は「Zulu time」を意味し、UTC(協定世界時)の別名です。Z で終わるタイムスタンプは現地時間ではなく UTC を表します。
24 時間制を 12 時間制に変換するにはどうすればよいですか?
1〜12 時の場合、時間はそのままです(0〜11 時には AM、12 時には PM を付けます)。13〜23 時は 12 を引いて PM を付けます。00:00 は 12:00 AM(深夜)、12:00 は 12:00 PM(正午)になります。
What is the Year 2038 problem?
32-bit signed Unix timestamps overflow on 19 January 2038 at 03:14:07 UTC, after which they wrap around to negative values that look like dates in 1901. Most modern systems use 64-bit timestamps and are unaffected, but legacy embedded devices, old databases, and 32-bit time_t in some C code still need to be audited.
How are leap seconds handled in Unix time?
Unix time pretends leap seconds do not exist. The clock simply repeats or stretches the affected second, so a Unix timestamp is not a strict count of elapsed SI seconds. For most applications this is fine, but precision-timing code (astronomy, GPS, high-frequency trading) needs TAI or UTC with explicit leap-second handling.