FILETIME Converter

Windows FILETIME → Unix タイムスタンプ コンバーター

Windows FILETIME を Unix 時間に変換します。正確な式と大きな値への対応。出力は秒、ミリ秒、ISO 8601、可読形式。

1601-01-01 UTC からの 100 ナノ秒間隔

現在の時刻 — Windows FILETIME
Unix タイムスタンプ(秒)

Windows の FILETIME とは?

FILETIME は Windows API 全体で使われるタイムスタンプ形式です。1601 年 1 月 1 日 00:00:00 UTC(Windows が内部で使うグレゴリオ暦サイクルの開始)からの 100 ナノ秒間隔(1000 万分の 1 秒)の数を数える 64 ビット値です。

  • エポック:1601-01-01 00:00:00 UTC
  • 分解能:100 ナノ秒刻み(毎秒 10,000,000)
  • 幅:64 ビット符号なし整数。多くの場合 2 つの 32 ビット DWORD として格納される(dwLowDateTime、dwHighDateTime)
  • 見られる場所:NTFS のファイル時刻、Windows レジストリ、Active Directory(例:lastLogonTimestamp、pwdLastSet)、イベントログ

FILETIME を Unix タイムスタンプに変換する方法

FILETIME エポック(1601)と Unix エポック(1970)の間には 11,644,473,600 秒あります。FILETIME を 10,000,000 で割って秒を求め、そのオフセットを引きます。

  • Unix seconds = FILETIME / 10000000 − 11644473600
  • Unix milliseconds = FILETIME / 10000 − 11644473600000
  • 例:133444736000000000 → 1700000000 秒 → 2023-11-14 22:13:20 UTC
  • 逆方向:FILETIME = (Unix milliseconds + 11644473600000) × 10000

精度とエッジケース

現在時刻の FILETIME はおよそ 1.3 × 10^17 で、JavaScript の数値の安全な整数範囲(2^53)を超えます。このコンバーターは BigInt で値を解析するため、精度は失われません。ミリ秒未満の精度(末尾 4 桁)は、ミリ秒の Unix タイムスタンプに変換する際に切り捨てられます。

  • Active Directory は「なし」を表すために 0 または 9223372036854775807 を格納することがある — これらはセンチネルであり、実際の日付ではない
  • FILETIME は常に UTC。タイムゾーンは結果を表示するときにのみ適用する
  • ローカル時間の変種(FileTimeToLocalFileTime によるもの)はすでにオフセットを含む — まず UTC に戻すこと

関連するタイムスタンプ形式コンバーター

FILETIME の実用的なヒント

実際の FILETIME 変換で引っかかりやすい点をいくつか:

  • PowerShell:[DateTime]::FromFileTimeUtc($ft) はスクリプトでの標準的な変換
  • Active Directory は「無期限」を表すために定数 9223372036854775807(Int64.MaxValue)をよく使う — 日付ではなくセンチネルとして扱う
  • AD は「未設定」を表すために 0 も使う。0 と Int64.MaxValue の両方を特別に扱う
  • NTFS のファイル時刻には作成・最終書き込み・最終アクセスの 3 種類がある — すべて同じ FILETIME 形式を使う
  • FILETIME が 2 つの 32 ビット DWORD に分割されている場合は、変換前に (high << 32) | low として結合する

FAQ

FILETIME のエポックとは?
FILETIME は 1601 年 1 月 1 日 00:00:00 UTC からの 100 ナノ秒間隔を数えます。これは Windows がグレゴリオ暦に使う基準日です。
なぜ 11644473600 秒を引くのか?
これは 1601 年の FILETIME エポックと 1970 年の Unix エポックの間の秒数です。FILETIME を 10,000,000 で割ると 1601 年からの秒になり、オフセットを引くと基準が 1970 年に移ります。
2 つの 32 ビット値として保存された FILETIME を変換するには?
FILETIME = (dwHighDateTime × 4294967296) + dwLowDateTime として結合し、その 64 ビット値を通常どおり変換します。