Question
How can I correctly convert a Unix timestamp to a DateTime in C#, and convert a DateTime back to a Unix timestamp?
I found example code, but it starts discussing millisecond and nanosecond differences, which made the solution unclear.
I also saw a related discussion on MSDN about seconds since the Unix epoch in C#.
Here is the code I currently have:
public double CreatedEpoch
{
get
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
TimeSpan span = this.Created.ToLocalTime() - epoch;
return span.TotalSeconds;
}
set
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
this.Created = epoch.AddSeconds(value);
}
}
Is this the correct approach, especially with regard to time zones and Unix time being measured in seconds since 1970-01-01 UTC?
Short Answer
By the end of this page, you will understand what a Unix timestamp is, how it relates to UTC, how to convert between Unix time and DateTime in C#, and which common mistakes to avoid. You will also see safer modern approaches and practical examples you can use in real code.
Concept
Unix time is the number of seconds that have passed since 1970-01-01 00:00:00 UTC, often called the Unix epoch.
In C#, the main challenge is not the subtraction itself. The real challenge is handling time zones correctly.
A Unix timestamp is always based on UTC, not local time. That means:
- When converting a
DateTimeto a Unix timestamp, first make sure theDateTimerepresents a UTC moment. - When converting a Unix timestamp back to a
DateTime, the result should usually start as UTC.
This matters because the same instant can look different in different time zones:
2024-01-01 12:00 UTC2024-01-01 07:00in UTC-52024-01-01 13:00in UTC+1
These are different clock displays of the same moment.
In real programming, Unix timestamps are widely used in:
- APIs
- databases
- logging systems
- authentication tokens
- event tracking
- distributed systems
If you mix local time and UTC incorrectly, you can create bugs such as:
- timestamps being off by several hours
- values changing depending on the server location
- daylight saving time errors
- incorrect ordering of events
In modern C#, the best tool for this is often DateTimeOffset, because it represents a point in time more clearly than . It includes an offset from UTC and has built-in Unix conversion methods.
Mental Model
Think of Unix time as a universal stopwatch that started at midnight on 1970-01-01 UTC.
- A Unix timestamp is just the stopwatch reading in seconds.
- A
DateTimeis like a calendar clock display. - A local time zone is like choosing which wall clock you want to look at.
The important idea is this:
- Unix timestamp = one exact moment
- Local time = how that moment appears in a specific region
So when converting:
- Convert the wall-clock time to the universal stopwatch reading.
- Or take the stopwatch reading and display it as UTC or local time.
If you start mixing stopwatch values with local wall clocks too early, your result can shift unexpectedly.
Syntax and Examples
The safest modern approach in C# is to use DateTimeOffset.
Convert Unix timestamp to date/time
long unixSeconds = 1704067200;
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(unixSeconds);
DateTime utcDateTime = dto.UtcDateTime;
DateTime localDateTime = dto.LocalDateTime;
Explanation:
FromUnixTimeSecondscreates aDateTimeOffsetfrom Unix seconds.UtcDateTimegives the UTC version.LocalDateTimeconverts that same moment to the machine's local time zone.
Convert date/time to Unix timestamp
DateTime created = DateTime.UtcNow;
long unixSeconds = new DateTimeOffset(created).ToUnixTimeSeconds();
If your DateTime is local time:
DateTime localTime = DateTime.Now;
long unixSeconds = new DateTimeOffset(localTime).ToUnixTimeSeconds();
If you must use DateTime directly
DateTime epoch = DateTime(, , , , , , DateTimeKind.Utc);
DateTime utcTime = DateTime.UtcNow;
unixSeconds = ()(utcTime - epoch).TotalSeconds;
Step by Step Execution
Consider this example:
DateTime utcTime = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long unixSeconds = (long)(utcTime - epoch).TotalSeconds;
Step by step:
epochis set to1970-01-01 00:00:00 UTC.utcTimeis set to2024-01-01 00:00:00 UTC.utcTime - epochproduces aTimeSpan.- That
TimeSpancontains the total elapsed time between the two UTC moments. TotalSecondsreturns the difference in seconds.- Casting to
longremoves the fractional part.
Now convert it back:
Real World Use Cases
APIs
Many APIs send timestamps as Unix seconds or milliseconds because the format is compact and language-independent.
{ "createdAt": 1704067200 }
Logging and event tracking
Logs often use Unix timestamps so events can be compared consistently across servers in different time zones.
Authentication and security
JWT tokens and other auth systems often use Unix timestamps for expiration fields like exp.
Databases and storage
Some systems store timestamps as integers for easier sorting and transport.
Scheduled jobs
Background tasks may compare the current Unix timestamp with a stored timestamp to decide whether a job should run.
Real Codebase Usage
In real projects, developers usually avoid scattering manual epoch math throughout the codebase.
Common patterns include:
Using DateTimeOffset for serialization
public class EventRecord
{
public DateTimeOffset CreatedAt { get; set; }
public long CreatedAtUnix => CreatedAt.ToUnixTimeSeconds();
}
This keeps the main value as a proper date/time type and only converts when needed.
Guarding against ambiguous DateTime values
DateTime can have these Kind values:
UtcLocalUnspecified
Unspecified is risky because C# cannot always know how to interpret it.
Example guard clause:
public static long ToUnixSeconds(DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Unspecified)
ArgumentException();
DateTimeOffset(dateTime).ToUnixTimeSeconds();
}
Common Mistakes
1. Using local time for the Unix epoch
Broken example:
DateTime epoch = new DateTime(1970, 1, 1).ToLocalTime();
Why it is a problem:
- Unix time is defined from a UTC epoch.
- Converting the epoch to local time changes the reference point.
Correct:
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
2. Mixing local and UTC values
Broken example:
DateTime now = DateTime.Now;
long unixSeconds = (long)(now - epoch).TotalSeconds;
Why it is a problem:
DateTime.Nowis local time.epochmay be UTC.- Mixing them can lead to offset errors.
Correct:
DateTime now = DateTime.UtcNow;
long unixSeconds = ()(now - epoch).TotalSeconds;
Comparisons
| Approach | Best for | Pros | Cons |
|---|---|---|---|
DateTimeOffset.FromUnixTimeSeconds() / ToUnixTimeSeconds() | Most application code | Clear, built-in, handles offsets well | Requires newer .NET versions |
Manual DateTime + epoch subtraction | Learning or legacy code | Simple to understand | Easier to get UTC handling wrong |
DateTime.Now | Displaying local current time | Useful for UI | Not good as a basis for Unix time calculations |
DateTime.UtcNow | Timestamps and storage | Consistent across systems | Must convert to local time for display if needed |
DateTime vs DateTimeOffset
Cheat Sheet
// Unix timestamp -> DateTimeOffset
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(unixSeconds);
// Unix timestamp -> UTC DateTime
DateTime utc = DateTimeOffset.FromUnixTimeSeconds(unixSeconds).UtcDateTime;
// Unix timestamp -> Local DateTime
DateTime local = DateTimeOffset.FromUnixTimeSeconds(unixSeconds).LocalDateTime;
// DateTime -> Unix timestamp
long unix = new DateTimeOffset(dateTime).ToUnixTimeSeconds();
// Current Unix timestamp
long nowUnix = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
Rules:
- Unix epoch is
1970-01-01 00:00:00 UTC - Prefer
DateTimeOffsetover manual math - Use
UtcNowfor current timestamps - Convert to local time only for display
- Watch out for seconds vs milliseconds
- Avoid
DateTimeKind.Unspecifiedwhen possible
Manual UTC conversion:
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long unix = (long)(DateTime.UtcNow - epoch).TotalSeconds;
DateTime utc = epoch.AddSeconds(unix);
FAQ
How do I convert a Unix timestamp to a DateTime in C#?
Use DateTimeOffset.FromUnixTimeSeconds() or FromUnixTimeMilliseconds(), then read UtcDateTime or LocalDateTime.
Should I use DateTime or DateTimeOffset for Unix timestamps?
DateTimeOffset is usually better because it represents an exact point in time more clearly and has built-in Unix conversion methods.
Why is my converted time off by a few hours?
This usually happens because local time and UTC were mixed incorrectly during conversion.
What is the Unix epoch in C#?
It is 1970-01-01 00:00:00 UTC, the starting point for Unix timestamps.
Are Unix timestamps in seconds or milliseconds?
They can be either. Always check the source system. A 10-digit value is often seconds, while a 13-digit value is often milliseconds.
Can I store a Unix timestamp in a double?
You can, but long is usually better for whole-second or whole-millisecond timestamps because it avoids floating-point issues.
When should I convert UTC to local time?
Usually only when displaying the date/time to a user or formatting output for a specific region.
Mini Project
Description
Build a small C# utility that converts values both ways: from Unix timestamp to human-readable time, and from DateTime to Unix timestamp. This demonstrates the most important rule of time handling in real applications: keep the internal value in UTC and only convert to local time when needed.
Goal
Create a console program that reads a Unix timestamp, prints its UTC and local values, and also prints the current Unix timestamp.
Requirements
- Read a Unix timestamp in seconds and convert it to UTC time.
- Show the same moment in local time.
- Print the current Unix timestamp.
- Convert the current UTC time back into Unix seconds.
- Use
DateTimeOffsetfor the conversions.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Array Initialization Syntaxes Explained
Learn all common C# array initialization syntaxes with examples, rules, comparisons, and mistakes beginners often make.