Convert Unix Timestamp in C#

C# and .NET provide excellent support for Unix timestamps through DateTimeOffset (recommended) and DateTime. Since .NET 4.6, built-in methods make conversions straightforward.

Unix Timestamp to DateTime (.NET 4.6+)

C#
using System;

// From seconds (standard Unix timestamp)
long timestampSeconds = 1704067200;
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(timestampSeconds);
Console.WriteLine(dto);           // 2024-01-01 00:00:00 +00:00
Console.WriteLine(dto.UtcDateTime); // 2024-01-01 00:00:00

// From milliseconds
long timestampMs = 1704067200000;
DateTimeOffset dtoMs = DateTimeOffset.FromUnixTimeMilliseconds(timestampMs);
Console.WriteLine(dtoMs);         // 2024-01-01 00:00:00 +00:00

// Convert to local time
DateTime localTime = dto.LocalDateTime;
Console.WriteLine(localTime);     // Depends on system timezone

DateTime to Unix Timestamp (.NET 4.6+)

C#
using System;

// Current timestamp in seconds
long nowSeconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
Console.WriteLine(nowSeconds);    // e.g., 1704067200

// Current timestamp in milliseconds
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Console.WriteLine(nowMs);         // e.g., 1704067200000

// From specific DateTime (must specify UTC)
DateTime specificDate = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTimeOffset dto = new DateTimeOffset(specificDate);
long timestamp = dto.ToUnixTimeSeconds();
Console.WriteLine(timestamp);     // 1704067200

// From DateTimeOffset directly
DateTimeOffset dto2 = new DateTimeOffset(2024, 1, 1, 0, 0, 0, TimeSpan.Zero);
Console.WriteLine(dto2.ToUnixTimeSeconds()); // 1704067200

Legacy .NET (Before 4.6)

For older .NET Framework versions without built-in methods:

C#
using System;

public static class UnixTimeHelper
{
    private static readonly DateTime UnixEpoch = 
        new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    // Unix timestamp to DateTime
    public static DateTime FromUnixTimestamp(long timestamp)
    {
        return UnixEpoch.AddSeconds(timestamp);
    }

    // DateTime to Unix timestamp
    public static long ToUnixTimestamp(DateTime dateTime)
    {
        if (dateTime.Kind != DateTimeKind.Utc)
            dateTime = dateTime.ToUniversalTime();
        
        return (long)(dateTime - UnixEpoch).TotalSeconds;
    }
}

// Usage
DateTime date = UnixTimeHelper.FromUnixTimestamp(1704067200);
Console.WriteLine(date); // 2024-01-01 00:00:00

long ts = UnixTimeHelper.ToUnixTimestamp(DateTime.UtcNow);
Console.WriteLine(ts);   // Current Unix timestamp

Timezone Handling

C#
using System;

long timestamp = 1704067200;
DateTimeOffset utcTime = DateTimeOffset.FromUnixTimeSeconds(timestamp);

// Convert to specific timezone
TimeZoneInfo estZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
// On Linux/macOS use: TimeZoneInfo.FindSystemTimeZoneById("America/New_York")
DateTimeOffset estTime = TimeZoneInfo.ConvertTime(utcTime, estZone);
Console.WriteLine($"UTC: {utcTime}");     // 2024-01-01 00:00:00 +00:00
Console.WriteLine($"EST: {estTime}");     // 2023-12-31 19:00:00 -05:00

// Convert to local system timezone
DateTimeOffset localTime = utcTime.ToLocalTime();
Console.WriteLine($"Local: {localTime}"); // Depends on system

// Create time in specific timezone, get Unix timestamp
TimeZoneInfo tokyoZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
// On Linux/macOS use: TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo")
DateTime tokyoMidnight = new DateTime(2024, 1, 1, 0, 0, 0);
DateTimeOffset tokyoTime = new DateTimeOffset(tokyoMidnight, tokyoZone.BaseUtcOffset);
Console.WriteLine(tokyoTime.ToUnixTimeSeconds()); // 1704034800

Formatting

C#
using System;

long timestamp = 1704067200;
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(timestamp);

// Standard format strings
Console.WriteLine(dto.ToString("o"));              // 2024-01-01T00:00:00.0000000+00:00 (ISO 8601)
Console.WriteLine(dto.ToString("s"));              // 2024-01-01T00:00:00 (sortable)
Console.WriteLine(dto.ToString("u"));              // 2024-01-01 00:00:00Z (universal)
Console.WriteLine(dto.ToString("R"));              // Mon, 01 Jan 2024 00:00:00 GMT (RFC 1123)

// Custom format strings
Console.WriteLine(dto.ToString("yyyy-MM-dd"));     // 2024-01-01
Console.WriteLine(dto.ToString("yyyy-MM-dd HH:mm:ss")); // 2024-01-01 00:00:00
Console.WriteLine(dto.ToString("MMMM dd, yyyy"));  // January 01, 2024
Console.WriteLine(dto.ToString("ddd, dd MMM yyyy HH:mm:ss zzz")); // Mon, 01 Jan 2024 00:00:00 +00:00

// With specific culture
using System.Globalization;
var german = new CultureInfo("de-DE");
Console.WriteLine(dto.ToString("D", german));      // Montag, 1. Januar 2024

Parsing Date Strings

C#
using System;
using System.Globalization;

// Parse ISO 8601
DateTimeOffset dto1 = DateTimeOffset.Parse("2024-01-01T00:00:00Z");
Console.WriteLine(dto1.ToUnixTimeSeconds()); // 1704067200

// Parse with exact format
DateTimeOffset dto2 = DateTimeOffset.ParseExact(
    "2024-01-01 00:00:00",
    "yyyy-MM-dd HH:mm:ss",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal);
Console.WriteLine(dto2.ToUnixTimeSeconds()); // 1704067200

// TryParse for safe parsing
if (DateTimeOffset.TryParse("2024-01-01T00:00:00Z", out DateTimeOffset result))
{
    Console.WriteLine(result.ToUnixTimeSeconds());
}

// Parse with timezone info
DateTimeOffset dto3 = DateTimeOffset.Parse("2024-01-01T00:00:00-05:00");
Console.WriteLine(dto3.ToUnixTimeSeconds()); // 1704085200 (5 hours later than UTC)

Common Pitfalls

DateTime.Kind Confusion

A DateTime without explicit Kind defaults to Unspecified, which can cause incorrect conversions.

// ❌ Wrong - Kind is Unspecified, treated as local time
DateTime dt = new DateTime(2024, 1, 1, 0, 0, 0);
DateTimeOffset dto = new DateTimeOffset(dt); // Uses local offset!

// ✅ Correct - specify UTC explicitly
DateTime dtUtc = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTimeOffset dtoUtc = new DateTimeOffset(dtUtc);
Console.WriteLine(dtoUtc.ToUnixTimeSeconds()); // 1704067200

Seconds vs Milliseconds

Using the wrong method produces wildly incorrect dates.

long tsMillis = 1704067200000;

// ❌ Wrong - treating milliseconds as seconds
var wrong = DateTimeOffset.FromUnixTimeSeconds(tsMillis);
Console.WriteLine(wrong); // Year 55963!

// ✅ Correct - use milliseconds method
var correct = DateTimeOffset.FromUnixTimeMilliseconds(tsMillis);
Console.WriteLine(correct); // 2024-01-01 00:00:00 +00:00

Timezone ID Differences

Windows uses different timezone IDs than Linux/macOS (IANA).

// Windows
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

// Linux/macOS (IANA)
TimeZoneInfo.FindSystemTimeZoneById("America/New_York");

// Cross-platform (.NET 6+): Use TimeZoneInfo.TryConvertIanaIdToWindowsId()
// or NodaTime library for consistent behavior

Edge Cases

C#
using System;

// Negative timestamps (before 1970)
DateTimeOffset before1970 = DateTimeOffset.FromUnixTimeSeconds(-86400);
Console.WriteLine(before1970); // 1969-12-31 00:00:00 +00:00

// Minimum supported Unix timestamp
DateTimeOffset min = DateTimeOffset.FromUnixTimeSeconds(-62135596800);
Console.WriteLine(min); // 0001-01-01 00:00:00 +00:00

// Maximum supported Unix timestamp  
DateTimeOffset max = DateTimeOffset.FromUnixTimeSeconds(253402300799);
Console.WriteLine(max); // 9999-12-31 23:59:59 +00:00

// Overflow handling - throws ArgumentOutOfRangeException
try
{
    DateTimeOffset invalid = DateTimeOffset.FromUnixTimeSeconds(long.MaxValue);
}
catch (ArgumentOutOfRangeException)
{
    Console.WriteLine("Timestamp out of range!");
}

// Millisecond precision
DateTimeOffset precise = DateTimeOffset.FromUnixTimeMilliseconds(1704067200123);
Console.WriteLine(precise.Millisecond); // 123

// Ticks (100-nanosecond intervals)
Console.WriteLine(precise.UtcTicks); // 638396256001230000

TimeSpan Calculations

C#
using System;

DateTimeOffset start = DateTimeOffset.FromUnixTimeSeconds(1704067200);
DateTimeOffset end = DateTimeOffset.FromUnixTimeSeconds(1704153600);

// Calculate difference
TimeSpan diff = end - start;
Console.WriteLine($"Seconds: {diff.TotalSeconds}");   // 86400
Console.WriteLine($"Minutes: {diff.TotalMinutes}");   // 1440
Console.WriteLine($"Hours: {diff.TotalHours}");       // 24
Console.WriteLine($"Days: {diff.TotalDays}");         // 1

// Add/subtract time
DateTimeOffset tomorrow = start.AddDays(1);
DateTimeOffset yesterday = start.AddDays(-1);
Console.WriteLine($"Tomorrow: {tomorrow.ToUnixTimeSeconds()}");
Console.WriteLine($"Yesterday: {yesterday.ToUnixTimeSeconds()}");

// Add specific time spans
DateTimeOffset later = start.Add(new TimeSpan(2, 30, 0)); // 2h 30m
Console.WriteLine($"2h 30m later: {later}");

// Using TimeSpan directly
DateTimeOffset result = start + TimeSpan.FromHours(5.5);
Console.WriteLine($"5.5 hours later: {result}");

Frequently Asked Questions

What is the best way to handle Unix timestamps in C#?

Use DateTimeOffset for most cases—it has built-in FromUnixTimeSeconds() and ToUnixTimeSeconds() methods since .NET 4.6. For older frameworks, manually add seconds to the Unix epoch (1970-01-01).

Does C# use seconds or milliseconds for Unix timestamps?

The .NET methods support both: FromUnixTimeSeconds() for seconds and FromUnixTimeMilliseconds() for milliseconds. Choose based on your data source—10 digits means seconds, 13 digits means milliseconds.

What is the difference between DateTime and DateTimeOffset?

DateTime represents a date and time, optionally with a Kind (Utc, Local, Unspecified). DateTimeOffset always includes a timezone offset, making it unambiguous and preferred for Unix timestamp conversions.

How do I handle timezones when converting Unix timestamps in C#?

Unix timestamps are always UTC. Use DateTimeOffset.FromUnixTimeSeconds() which returns UTC, then convert to local time with .LocalDateTime or to a specific timezone with TimeZoneInfo.ConvertTime().