Windows FILETIME / AD Password-Last-Set Decoder
Convert a Windows FILETIME value (used in Active Directory attributes like pwdLastSet, lastLogonTimestamp, and accountExpires) to a human-readable date and time, or the reverse.
SINCE 1601-01-01
Common Active Directory Attributes That Use FILETIME
| pwdLastSet | When the account's password was last changed. 0 means the user must change their password at next logon. |
| lastLogonTimestamp | An approximate, replicated last-logon time (not exact — updated infrequently to reduce replication traffic). |
| lastLogon | An exact, per-domain-controller last-logon time (not replicated between DCs, so it only reflects logons to that specific DC). |
| accountExpires | When the account expires. 0 or the max value (9223372036854775807) both effectively mean the account never expires. |
| badPasswordTime | The last time an incorrect password was entered for the account. |
This tool decodes and encodes Windows FILETIME values into human-readable dates and vice versa, ensuring precise conversions for Active Directory timestamps.
Features of Windows FILETIME / AD Password-Last-Set Decoder
- Decode and encode in one tool — convert a raw FILETIME value into a human-readable date, or go the other direction and generate a FILETIME value from a chosen date and time
- Accepts decimal or hex input — paste the value exactly as it appears in
ldp.exe, PowerShell, ADSI Edit, or any LDAP browser, without manually converting formats first - Precision-safe for real 64-bit values — built with native BigInt arithmetic, so 18-digit FILETIME values (the normal length for a current timestamp) decode exactly, with no silent rounding errors
- Special-value detection — automatically recognizes
0(“never set”) and the maximum 64-bit value9223372036854775807/0x7FFFFFFFFFFFFFFF(“never expires”), the two values that would otherwise decode to meaningless dates - Both UTC and local time shown — see the exact UTC timestamp alongside your browser’s local time conversion, with a relative “X days ago” readout
- Quick-reference table — a built-in cheat sheet explaining what pwdLastSet, lastLogon, lastLogonTimestamp, accountExpires, and badPasswordTime actually mean
- One-click copy on every output value — decimal, hex, UTC string, or local time string
- 100% private — all conversion happens locally in your browser; nothing you paste is sent anywhere, which matters when the values you’re decoding are pulled from a live directory
How to Use the FILETIME Decoder?
- Choose Decode or Encode. Use Decode to turn a raw FILETIME number into a date, or Encode to generate a FILETIME value from a date you pick.
- To decode: paste the value into the input field. It can be a plain decimal integer or a
0x-prefixed hex value — the tool detects which one you’ve entered automatically. - Check the special-value badges. If the value is exactly
0or the maximum 64-bit integer, the tool flags it immediately instead of showing a confusing date, since both are common sentinel values in Active Directory rather than real timestamps. - Read the full breakdown. Once a value decodes successfully, you’ll see the UTC time, your local time, the Unix timestamp equivalent, and both the decimal and hex FILETIME forms.
- To encode: switch to the Encode tab, pick a date and UTC time, and the corresponding FILETIME value appears instantly in both decimal and hex.
- Copy what you need. Every value has its own Copy button — grab just the one format you need without manually selecting text.
Understanding Active Directory Timestamps: pwdLastSet, lastLogon, and accountExpires Explained
If you’ve ever pulled a raw attribute value from Active Directory and found an 18-digit number like 132837264000000000 instead of an actual date, you’ve run into Windows FILETIME — one of the more confusing corners of AD for anyone who hasn’t worked with it before. This explains exactly what that number means, why it’s formatted the way it is, and how to read the handful of AD attributes that use it.
What Is a Windows FILETIME Value?
FILETIME is a 64-bit number representing the count of 100-nanosecond intervals since January 1, 1601, at 00:00:00 UTC. That reference date isn’t arbitrary nonsense — 1601 was chosen because it’s the start of the first 400-year Gregorian calendar cycle, which made certain date-math calculations cleaner for the engineers who designed the format decades ago.
The format shows up throughout the Windows API and, by extension, throughout Active Directory, because AD stores several of its own timestamp attributes using this same structure rather than a more familiar format like Unix time (seconds since 1970) or an ISO 8601 date string.
This is why a raw AD timestamp attribute, viewed through a tool like ldp.exe or a direct LDAP query, often shows up as a long string of digits instead of a readable date — the directory is storing the literal 100-nanosecond count, and it’s up to whatever tool displays it to do the conversion.
Why 100-Nanosecond Intervals?
A 64-bit integer counting seconds would only be able to represent a span of roughly 292 billion years — vastly more range than necessary, at the cost of only second-level precision. Counting in 100-nanosecond units instead trades some of that enormous range for far finer precision (still spanning over 58,000 years from the 1601 epoch, more than enough), which matters for operations like file system timestamps where multiple events can legitimately happen within the same second and still need to be ordered correctly.
The Math Behind the Conversion
Converting FILETIME to a standard Unix timestamp (seconds since January 1, 1970) requires two steps:
- Subtract the epoch difference. The gap between January 1, 1601, and January 1, 1970, is exactly 116,444,736,000,000,000 in 100-nanosecond units. Subtracting this constant re-bases the count from the 1601 epoch to the 1970 epoch.
- Convert the unit. Divide the result by 10,000,000 to convert from 100-nanosecond intervals into whole seconds (or by 10,000 to get milliseconds, which is what most programming languages’ native Date objects expect).
The reverse process — turning a normal date into a FILETIME value — just runs the same math backwards: convert the date to milliseconds since 1970, multiply by 10,000 to get 100-nanosecond units, then add the epoch-difference constant back.
Why this needs careful handling in code. A real-world FILETIME value is typically an 18-digit number. JavaScript’s native Number type can only represent integers exactly up to about 9 quadrillion (2^53 − 1) — a 16-digit ceiling. Past that point, large integers silently lose precision, which would produce a timestamp that’s subtly wrong by seconds, minutes, or more, without throwing any error to warn you. Any tool decoding real FILETIME values needs to use an arbitrary-precision integer type (BigInt, in JavaScript’s case) to avoid this — a detail that’s easy to miss and produces results that look plausible but are quietly incorrect.
The Active Directory Attributes That Use FILETIME
A handful of commonly referenced AD attributes store their values in this format. Knowing what each one actually represents — and what its edge cases mean — is where most of the real confusion lives, separate from the date-math itself.
pwdLastSet — the date and time the account’s password was last changed. A value of 0 has a specific meaning here: it signals that the user is required to change their password at next logon, not that the password was changed at midnight on January 1, 1601. Administrators sometimes set this to 0 deliberately to force a password reset.
lastLogon — records the last time a user logged on, but with an important caveat: this attribute is not replicated between domain controllers. It only reflects logons to the specific DC you’re querying. If a user authenticates against different DCs throughout the day (which is normal in any multi-DC environment), each DC has its own separate, un-synced value. This makes lastLogon accurate but incomplete on its own.
lastLogonTimestamp — exists specifically to solve the problem above. It is replicated across domain controllers, giving administrators a single, directory-wide view of roughly when a user last logged on. The trade-off is precision: to avoid generating excessive replication traffic, Windows only updates this value when it differs from the current value by more than a configurable window (14 days by default). So lastLogonTimestamp is approximate by design — useful for “has this account been used in the last month?” style questions, not for pinpointing an exact logon time.
accountExpires — the date after which the account can no longer log on. This is where the second special value matters: 0 and the maximum possible 64-bit integer, 9223372036854775807 (0x7FFFFFFFFFFFFFFF), both effectively mean “this account never expires.” Neither should be interpreted as a literal date.
badPasswordTime — the last time someone entered an incorrect password for the account, commonly checked alongside badPwdCount when investigating potential lockouts or brute-force attempts.
Why “0” and the Maximum Value Show Up So Often
These two sentinel values are the single biggest source of confusion when decoding AD timestamps by hand, because a naive conversion doesn’t fail — it just produces a technically-valid-looking but meaningless date.
Feed 0 through the standard FILETIME-to-date math and you get January 1, 1601 — the epoch itself, not “never happened.” Feed the maximum 64-bit value through the same math and you get a date far in the future (year 30828, specifically), not “this account is set to expire in the year 30828.” Both results are mathematically correct outputs of the formula and both are practically meaningless without knowing the convention behind them. Any tool or script decoding these values should check for these two special cases explicitly, rather than trusting the raw converted date at face value.
Reading These Values in Practice
When you’re troubleshooting an account issue, the attribute you need depends on the question you’re asking:
- “When did this user last change their password?” →
pwdLastSet - “Has this account been used recently, directory-wide?” →
lastLogonTimestamp(approximate, replicated) - “Exactly when did this user authenticate against this specific DC?” →
lastLogon(exact, not replicated) - “Is this account set to expire, and when?” →
accountExpires(watch for the 0 / max-value “never” cases) - “Is someone trying to brute-force this account?” →
badPasswordTimecombined withbadPwdCount
Have a raw value to check right now? Use the Windows FILETIME / AD Password-Last-Set Decoder above — paste in any pwdLastSet, lastLogon, or accountExpires
Explore More Free Tools
All tools run entirely in your browser — free, no sign-up, nothing stored.



