FileTime vs. Unix Time: Key Differences and Conversion Methods
What each format is
- FileTime (Windows FILETIME): 64-bit integer counting 100-nanosecond intervals since 00:00:00 UTC on January 1, 1601 (Gregorian). Used by NTFS, Win32 APIs, and Windows runtimes.
- Unix Time (POSIX/time_t): integer (commonly 32‑ or 64‑bit) counting seconds since 00:00:00 UTC on January 1, 1970. Widely used on Unix-like systems and in many programming languages.
Key differences
- Epochs: FileTime epoch = 1601-01-01; Unix epoch = 1970-01-01.
- Resolution: FileTime = 100 ns (10^-7 s) ticks; Unix time = 1 s (though many modern APIs support subsecond precision as float or separate fields).
- Range: FILETIME’s 64-bit ticks cover far wider date range than 32-bit Unix time (which overflows in 2038). 64-bit time_t avoids that overflow.
- Typical storage/representation: FileTime uses two 32-bit fields (dwLowDateTime, dwHighDateTime) or a 64-bit integer; Unix time commonly a single signed integer/64-bit integer or a floating-point seconds value for fractions.
- Time zone: Both measure absolute UTC instants; localized display requires conversion to local time separately.
Conversion basics (math)
- Ticks per second = 10,000,000 (because each tick = 100 ns).
- Offset between epochs (in FILETIME ticks) = 116444736000000000. This equals the number of 100‑ns intervals from 1601-01-01 to 1970-01-01.
Formulas:
- FILETIME (ticks) -> Unix seconds: unix_seconds = (filetime_ticks – 116444736000000000) / 10_000_000
- Unix seconds -> FILETIME ticks: filetime_ticks = unix_seconds10_000_000 + 116444736000000000
- For subsecond precision using milliseconds or nanoseconds, multiply/divide accordingly (e.g., multiply unix seconds by 1_000 to get milliseconds, by 1_000_000000 for nanoseconds).
Example conversions (code snippets)
C/C++ (Win32 style, using 64-bit integer)
c
// FILETIME -> unix time (seconds) int64_t filetime_to_unix(uint64_t ft) { const uint64_t EPOCH_DIFF = 116444736000000000ULL; return (int64_t)((ft - EPOCH_DIFF) / 10000000ULL); } // unix time (seconds) -> FILETIME uint64_t unix_to_filetime(int64_t unix_sec) { const uint64_t EPOCH_DIFF = 116444736000000000ULL; return (uint64_t)unix_sec 10000000ULL + EPOCHDIFF; }
C# (.NET)
csharp
// From FileTime (long) to DateTime DateTime dt = DateTime.FromFileTimeUtc(filetimeLong); // From DateTime or Unix seconds to FileTime long ft = dt.ToFileTimeUtc(); // or from unix seconds: long ft2 = unixSeconds 10_000000L + 116444736000000000L;
PowerShell
powershell
# FILETIME -> DateTime [datetime]::FromFileTimeUtc(130927962789982434) # Unix seconds -> DateTime [datetime]::UnixEpoch.AddSeconds(1610000000)
Python
python
# FILETIME ticks -> unix seconds EPOCH_DIFF = 116444736000000000 unix = (filetime_ticks - EPOCH_DIFF) / 10_000_000 # unix seconds -> FILETIME filetime = int(unix_seconds * 10_000_000) + EPOCH_DIFF
Practical tips and pitfalls
- Always treat both values as UTC instants; convert to local time only for display.
- Beware of signed/unsigned types and overflow when using 32-bit integers. Use 64-bit integers for FILETIME math.
- When converting FILETIME stored as two 32-bit parts, combine low/high into a 64-bit value: ticks = ((uint64_t)high << 32) | low.
- For high-precision timestamps (subsecond), keep fractional seconds explicitly (milliseconds, microseconds, or 100‑ns ticks) instead of truncating to whole seconds.
- FAT filesystem and some Windows APIs may store or return local times—use documented API helpers (FileTimeToSystemTime, FileTimeToLocalFileTime) when appropriate.
Quick reference table
| Concept | FileTime | Unix Time |
|---|---|---|
| Epoch | 1601-01-01 UTC | 1970-01-01 UTC |
| Unit | 100 ns ticks | 1 second (commonly) |
| Typical type | 64-bit integer / FILETIME struct | ⁄64-bit integer or float |
| Conversion constant | 116444736000000000 ticks offset | same (used in formulas) |
| Common API helpers | GetFileTime, FileTimeToSystemTime | time(), gmtime(), localtime() |
When to use which
- Use FileTime when interacting with Windows system calls, NTFS metadata, or Win32/COM APIs.
- Use Unix time for POSIX systems, inter-process simple numeric timestamps, or cross-platform APIs that expect seconds since 1970. Convert at the boundary between systems.
If you want, I can add a ready-to-copy utility function in the language you use (Go, Rust, Java, JavaScript, etc.).
Leave a Reply