The formats
- Ticks.
DateTime.Tickscounts 100-nanosecond intervals since 0001-01-01 00:00. The Unix epoch is tick 621,355,968,000,000,000 (DateTime.UnixEpoch.Ticks). Ticks carry no time zone; theKindsays how to read them. - Unix time. Seconds (or milliseconds, as JavaScript's
Date.now()) since 1970-01-01 UTC, ignoring leap seconds. UseDateTimeOffset.FromUnixTimeSecondsandToUnixTimeMilliseconds; they floor, so 1969-12-31 23:59:59.5 is second -1. Nanoseconds (Go, OpenTelemetry) have no .NET method: divide by 100 to get ticks. Alongonly holds nanoseconds from 1677 to 2262. - FILETIME. 100-nanosecond intervals since 1601-01-01 UTC, used by Windows APIs and Active Directory (
lastLogonTimestamp,pwdLastSet,accountExpires).DateTime.FromFileTimeUtcreads it;ToFileTimeUtcthrows for dates before 1601. - OLE Automation dates. Days since 1899-12-30 as a
double, the time of day as the fraction: Excel's serial dates, VBA and COM.DateTime.FromOADaterounds to the millisecond and returnsKindUnspecified. Before 1899-12-30 the fraction still counts forward, so -1.25 is 1899-12-29 06:00, not 18:00.ToOADatethrows before year 100. - DateTime.ToBinary. Ticks plus the
Kindin the two top bits. A Local value is stored as the UTC instant with the top bit set, which makes thelongnegative;FromBinaryconverts it to the local time zone of whichever machine reads it. - /Date(...)/ JSON. Milliseconds since the Unix epoch, written by
DataContractJsonSerializer, old ASP.NET and Newtonsoft.Json withDateFormatHandling.MicrosoftDateFormat. An offset such as+0200does not change the instant; it only records that the value was local time there.System.Text.Jsoncannot read this format and throws aJsonException.
DateTime.Parse and the Z
DateTime.Parse("2026-09-26T10:20:30Z") does not give you 10:20 UTC. It converts to the local time zone of the machine and returns Kind Local: 12:20 on a server in Berlin, 10:20 on one set to UTC. Without an offset you get Kind Unspecified. To keep UTC, pass DateTimeStyles.AdjustToUniversal (with AssumeUniversal for strings without an offset), as the generated code does, or parse into a DateTimeOffset.
From JavaScript
JavaScript dates are Unix milliseconds. To read .NET ticks in JavaScript, use BigInt because ticks exceed Number.MAX_SAFE_INTEGER: new Date(Number((ticks - 621355968000000000n) / 10000n)). The other way: BigInt(date.getTime()) * 10000n + 621355968000000000n.
FAQ
How do I convert DateTime ticks to a Unix timestamp in C#?
new DateTimeOffset(utc).ToUnixTimeSeconds(), or (ticks - DateTime.UnixEpoch.Ticks) / TimeSpan.TicksPerSecond. Back: DateTimeOffset.FromUnixTimeSeconds(seconds).UtcDateTime.
Why is DateTime.ToBinary() negative?
For a Local DateTime it sets the highest bit to record the kind. The value is the UTC instant, converted back to the reading machine's local time by FromBinary.
How do I convert an Excel date number in C#?
DateTime.FromOADate(serial). Excel dates have no time zone, and the result has Kind Unspecified.
Can System.Text.Json read /Date(1234567890000)/?
No, it throws. Use Newtonsoft.Json or a custom JsonConverter that calls DateTimeOffset.FromUnixTimeMilliseconds.
What is a Windows FILETIME?
100-nanosecond intervals since 1601-01-01 UTC. Active Directory timestamps use it. DateTime.FromFileTimeUtc converts it.
Related tools
- C# DateTime format tester
- Windows and IANA time zone converter
- Cron expression builder for .NET
- GUID / UUID generator (v7 holds a timestamp)