Date and time · date formatsFILETIME to date and Active Directory timestamps
FILETIME is an 18-digit count of 100-nanosecond intervals since 1 January 1601. Windows stores file times this way, and Active Directory keeps lastLogonTimestamp, pwdLastSet and accountExpires in it. Paste the number, a hex value or a dwHigh/dwLow pair to get the UTC date at full precision.
Calculated in your browser — values are never sent anywhere
FILETIME is a 64-bit integer: the number of 100-nanosecond intervals since midnight UTC on 1 January 1601. The year starts a 400-year Gregorian cycle, which keeps leap-year arithmetic simple.
The same number sits in Active Directory attributes: lastLogonTimestamp, pwdLastSet, badPasswordTime, accountExpires. Get-ADUser and ADSI Edit show it as 18 digits, a debugger as 0x01DC…, and a Win32 structure as the pair dwHighDateTime and dwLowDateTime.
Two values are not dates. 0 means “not set” (pwdLastSet = 0 forces a password change at logon), and 9223372036854775807 in accountExpires means “never expires”. Turning them into the year 1601 or 30828 is a common script bug.
Part by part134355024000000000
134355024000000000
100-nanosecond intervals since 1601-01-01 00:00 UTC — 3 October 2026, 12:00
÷ 10,000,000
seconds since 1601
− 11,644,473,600
seconds between 1601 and 1970 — the rest is Unix time
How to do it yourself
[DateTime]::FromFileTimeUtc(134355024000000000)PowerShell and .NET: number → UTC date
(Get-Date).ToFileTimeUtc()PowerShell: the current moment → FILETIME
w32tm /ntte 134355024000000000Windows command line: number → date
03
What it looks like
values you meet in practice
Value
What it is
0
not set
116444736000000000
1970-01-01 00:00:00 UTC
125911584000000000
2000-01-01 00:00:00 UTC
134355024000000000
2026-10-03 12:00:00 UTC
0x01DD532EB74F2000
2026-10-03 12:00:00 UTC
9223372036854775807
never expires
04
Common mistakes
Dividing by 1000 as if it were Unix milliseconds lands far in the future. FILETIME counts 100-nanosecond ticks: divide by 10,000,000 and subtract 11,644,473,600 seconds.
lastLogon and lastLogonTimestamp differ: the first is not replicated and is per domain controller, the second replicates but lags by up to 14 days. For “who has not signed in for a month” use lastLogonTimestamp.
FILETIME is UTC. Shown as local time without conversion, a 9 am sign-in in Moscow appears as 6 am.
05
Frequently asked
Paste the 18-digit number from the attribute into the field on this page to get the date in UTC and in Moscow time. In PowerShell, [DateTime]::FromFileTimeUtc(value) does the same, and Get-ADUser -Properties LastLogonDate returns a ready date. Remember the attribute lags by up to two weeks, so it suits finding stale accounts rather than exact sign-in times.
The way Windows stores points in time: a 64-bit integer counting 100-nanosecond intervals since midnight UTC on 1 January 1601. File creation and modification times, event log records and Active Directory timestamps all use it. The number is usually 18 digits long; a Win32 structure splits it into two 32-bit halves, dwHighDateTime and dwLowDateTime.
lastLogon updates on every sign-in, but only on the domain controller that checked the password, and it does not replicate: to find the latest sign-in you query every controller. lastLogonTimestamp replicates across the domain but updates at most once every 9 to 14 days. For a “not signed in for a month” report use the second; for exact times, the first.
Zero in pwdLastSet is not a date but a flag: the user must change the password at next logon. The “User must change password at next logon” checkbox sets it. The reverse is writing -1, which makes the domain store the current time and lifts the requirement. Converting the zero to a date is meaningless — it gives 1 January 1601.
The account never expires. It is the largest signed 64-bit value, 0x7FFFFFFFFFFFFFFF, and Active Directory uses it as “no expiry”. Zero in accountExpires means the same. A script that converts the number literally lands in the year 30828 — a common source of odd account-expiry reports.
Subtract 116444736000000000 — the number of 100-nanosecond ticks between 1601 and 1970 — and divide by 10,000,000 to get Unix seconds. Divide by 10,000 for milliseconds. The other way: multiply Unix seconds by 10,000,000 and add the same constant. In JavaScript and other languages whose plain numbers cannot hold 18 digits exactly, use BigInt or a decimal type.