.NET represents time as the number of 100-nanosecond intervals since January 1, 0001 (UTC). This converter handles both directions: ticks ↔ Unix epoch ↔ ISO 8601.
The .NET DateTime structure measures time in 100-nanosecond intervals (ticks) since 0001-01-01 00:00:00 UTC (the start of the Gregorian calendar). The value is stored as a long (64-bit integer).
You'll see ticks values in .NET serialization output, JSON APIs from .NET backends, and in column values when .NET applications store time as BIGINT in databases. Current-era ticks are 18-19 digits long.
unix_seconds = (ticks / 10_000_000) - 62_135_596_800
Divide by 10 million for ticks-to-seconds, then subtract the offset between year 1 and year 1970 (which is the same as 621355968000000000 / 10000000).
ticks = (unix_seconds + 62_135_596_800) * 10_000_000
// Ticks to DateTime
long ticks = 638713440000000000L;
DateTime dt = new DateTime(ticks, DateTimeKind.Utc);
Console.WriteLine(dt.ToString("o")); // → "2025-01-01T00:00:00.0000000Z"
// DateTime to ticks
long t = DateTime.UtcNow.Ticks;
// Convert .NET ticks to Unix seconds
long unixSec = (ticks - 621355968000000000L) / 10000000L;
const DOTNET_OFFSET_SEC = 62135596800;
function ticksToDate(ticks) {
// Use BigInt for safety — ticks values exceed Number.MAX_SAFE_INTEGER's precision
const sec = Number(BigInt(ticks) / 10000000n) - DOTNET_OFFSET_SEC;
return new Date(sec * 1000);
}
function dateToTicks(date) {
return (BigInt(Math.floor(date.getTime() / 1000)) + BigInt(DOTNET_OFFSET_SEC)) * 10000000n;
}
Both use 100-nanosecond intervals, but the epoch is different:
1601-01-010001-01-01The difference is exactly 504,911,232,000,000,000 ticks (504911232 seconds × 10M). If you have a value that looks like a tick but conversions are off, check which epoch you're working with.