Real Epoch Converter logo realepochconverter
programming guide

C# Unix Timestamp: DateTimeOffset, DateTime & TimeZoneInfo

C# splits time into DateTime (with a confusing Kind property) and DateTimeOffset (which carries the offset). The Unix conversion helpers live on DateTimeOffset — and the DateTime.Kind ambiguity is the source of most C# timestamp bugs.

Get the current Unix timestamp

DateTimeOffset.UtcNow is the correct "now" for epoch work. The ToUnixTimeSeconds() and ToUnixTimeMilliseconds() extension methods return the integers directly.

C#
using System;

long sec = DateTimeOffset.UtcNow.ToUnixTimeSeconds();     // 1767225600
long ms  = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); // 1767225600123

// DateTime.UtcNow also works but hides the offset — prefer DateTimeOffset
long sec2 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();

Convert a timestamp to a date

DateTimeOffset.FromUnixTimeSeconds(ts) returns a UTC DateTimeOffset with zero offset. From there, .UtcDateTime gives a UTC DateTime, .ToLocalTime() converts to the machine's zone, and TimeZoneInfo.ConvertTime targets any named zone — DST rules included.

C#
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(1767225600);
dto.ToString("u");                                  // 2026-01-01 00:00:00Z

DateTime ist = TimeZoneInfo.ConvertTime(dto, TimeZoneInfo.FindSystemTimeZoneById("Asia/Kolkata")).DateTime;
Console.WriteLine(ist.ToString("yyyy-MM-dd HH:mm:ss"));  // 2026-01-01 05:30:00

Convert a date back to a timestamp

The classic DateTime approach relies on Kind: a DateTime whose Kind is Unspecified is assumed to be local by ToUniversalTime(), which is almost never what you mean. Prefer building a DateTimeOffset with an explicit offset — it has no ambiguity.

C#
// Ambiguity-free: DateTimeOffset with an explicit offset
var utc = new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero);
utc.ToUnixTimeSeconds();                            // 1767225600

// The DateTime.Kind trap:
var naive = new DateTime(2026, 1, 1, 0, 0, 0);      // Kind = Unspecified
new DateTimeOffset(naive).ToUnixTimeSeconds();      // treated as LOCAL — machine-dependent

Naive vs aware: Kind is a promise, not a guarantee

  • DateTime — has Kind: Utc, Local, or Unspecified. The last one is the trap: APIs silently assume local.
  • DateTimeOffset — always aware: wall-clock plus a fixed TimeSpan offset. Epoch helpers live here.
  • TimeZoneInfo — the only DST-aware conversion path; ConvertTime handles ambiguous and skipped times.
  • Rule: store and transmit UTC (DateTimeOffset with zero offset), convert at the display boundary, and never round-trip through Unspecified.

Native precision: milliseconds and 100ns ticks

DateTime/DateTimeOffset carry 100-nanosecond ticks, so UtcNow exposes millisecond resolution on Windows.NET's own epoch predates Unix: DateTime.Ticks counts 100ns intervals since 0001-01-01 — the .NET ticks converter on this site bridges the two epochs if you ever meet a raw ticks value.

Common pitfalls

  • DateTime.Kind = Unspecified — round-trips through ToUniversalTime() silently shift by the machine offset.
  • JSON — System.Text.Json needs an explicit converter for DateTimeOffset ↔ epoch if you're not using ISO strings.
  • DST — never add TimeSpans across a transition; use TimeZoneInfo.
  • Windows zone IDs"Asia/Kolkata" is IANA; on .NET (Core) it resolves via the ICU database, so prefer IANA names.

Try it live

Verify any timestamp in the epoch converter, or copy the current value from the C# snippet tab on the homepage.

First published · Last reviewed · Maintained and developed by the Real Epoch Converter team · [email protected] · Contact · Methodology

Unix time in every language

JavaScript · Python · PHP · SQL · Go · Java · C# · Rust · C++ · PowerShell

Prefer the point-and-click version? The epoch time converter on the home page handles seconds, milliseconds, and microseconds in any timezone — every snippet on this page produces the same value that tool shows.

Copied