How do you convert Unix epoch time into real time in C#? (Epoch beginning 1/1/1970)
-
1Unless I'm missing something, the "epoch" is simply the origin point of a particular timekeeping scheme. Examples include 1/1/0001, 1/1/1970 and 1/1/2000. It's more of an attribute of a scheme rather than a scheme (e.g., Julian) itself. – Bob Kaufman May 21 '10 at 16:01
-
8Time since epoch is the number of seconds since January 1, 1970 UTC. – Taylor Leese May 21 '10 at 16:02
-
Dup, with other answers: https://stackoverflow.com/q/3354893/712526 – jpaugh Oct 25 '18 at 14:19
14 Answers
UPDATE 2020
You can do this with DateTimeOffset
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(epochSeconds);
DateTimeOffset dateTimeOffset2 = DateTimeOffset.FromUnixTimeMilliseconds(epochMilliseconds);
And if you need the DateTime
object instead of DateTimeOffset
, then you can call the DateTime
property
DateTime dateTime = dateTimeOffset.DateTime;
Original answer
I presume that you mean Unix time, which is defined as the number of seconds since midnight (UTC) on 1st January 1970.
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime FromUnixTime(long unixTime)
{
return epoch.AddSeconds(unixTime);
}
-
83To get this to work correctly I had to change .AddSeconds to .AddMilliseconds. You will need to know whether your number is coming from Seconds or Milliseconds in order to get the correct result. So for instance the following date: 1406310305188 (July 25 2014). http://www.epochconverter.com/ will also let you check your conversion results. – jrandomuser Jul 30 '14 at 16:58
-
5You should either change the parameter type to double (because AddSeconds accepts double and therefore will downcast to double) or add a disclaimer to the method description that only 53 out of 64 bits of precision in the argument will be preserved. – tomosius May 03 '16 at 17:04
-
7@jrandomuser: Unix epoch time is traditionally represented as *seconds* since The Epoch. It's since become common to use *milliseconds* since The Epoch (for instance, JavaScript), but the classic definition is seconds. Bottom-line, just know what your input value is (seconds, milliseconds, ticks, whatever) and use the right `AddXYZ` method. – T.J. Crowder Jul 16 '17 at 08:11
-
First try with AddMilliseconds and if the year is still 1970 then do AddSeconds. This way it will work all the time without having to worry about milliseconds or seconds. Plus you can prevent an overflow excption. Passing a large number to AddSeconds will make the code crash – Tono Nam Oct 16 '19 at 18:52
-
The latest version of .Net (v4.6) just added built-in support for Unix time conversions. That includes both to and from Unix time represented by either seconds or milliseconds.
- Unix time in seconds to
DateTimeOffset
:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
to Unix time in seconds:
long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
- Unix time in milliseconds to
DateTimeOffset
:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
to Unix time in milliseconds:
long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Note: These methods convert to and from DateTimeOffset
. To get a DateTime
representation simply use the DateTimeOffset.DateTime
property:
DateTime dateTime = dateTimeOffset.UtcDateTime;

- 113,022
- 33
- 324
- 344
-
1I am getting `'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'` How would I go about resolving this? – Happy Bird Jul 24 '17 at 14:44
-
-
The same thing - 4.7.2 and have no FromUnixTimeMilliseconds method for DateTimeOffset... – Mikhail_Sam Oct 09 '18 at 08:51
-
1I got it. I don't need to create new object. It's a static method. – Mikhail_Sam Oct 09 '18 at 09:23
-
1I found the default values a bit confusing at first glance. Bc 1000 is the factor to convert from millis to seconds. – Tigerware Jun 09 '20 at 01:41
With all credit to LukeH, I've put together some extension methods for easy use:
public static DateTime FromUnixTime(this long unixTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
public static long ToUnixTime(this DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date - epoch).TotalSeconds);
}
Note the comment below from CodesInChaos that the above FromUnixTime
returns a DateTime
with a Kind
of Utc
, which is fine, but the above ToUnixTime
is much more suspect in that doesn't account for what kind of DateTime
the given date
is. To allow for date
's Kind
being either Utc
or Local
, use ToUniversalTime
:
public static long ToUnixTime(this DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds);
}
ToUniversalTime
will convert a Local
(or Unspecified
) DateTime
to Utc
.
if you dont want to create the epoch DateTime instance when moving from DateTime to epoch you can also do:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
-
6`ToUnixTime` only works correctly if date is in Utc. Either add a check, or convert it. (Personally I prefer the check) – CodesInChaos Feb 26 '12 at 14:07
-
3Just spent the past hour figuring out why this doesnt work. You need to work in `milliseconds` *not* seconds!!! – KristianB Sep 13 '12 at 14:14
-
7@KristianB: "Unix time" is traditionally seconds, not milliseconds, since The Epoch, although these days I'm careful to check what definition someone is using. Seconds used to be good enough, and gave us a reasonable range either side of The Epoch in signed 32-bit values. (And is why just after 3:14 a.m. on Jan 19th, 2038 GMT might be a bad time for some...) Using milliseconds is a more modern practice thanks to our routinely being able to throw around 64-bit values (both integral and double-precision IEEE-754)... – T.J. Crowder Jan 20 '13 at 14:04
-
5Thanks for the code. Just a slight recommendation when creating the Epoch base: be sure to explicitly set the Millisecond value to 0. i.e. var epoch = new DateTime(1970, 1, 1, 0/*h*/, 0/*m*/, 0/*s*/, 0 /*ms*/, DateTimeKind.Utc); If you don't explicitly set it the millisecond value seems to come out as 1. This caused some inconsistencies in my tests. – ctrlplusb Apr 28 '14 at 13:20
-
2You should use `AddMilliseconds` and you should use Double NOT Float. Otherwise you'll end up with a wrong time. – Axel Mar 31 '16 at 16:51
You actually want to AddMilliseconds(milliseconds), not seconds. Adding seconds will give you an out of range exception.

- 283
- 3
- 2
-
Why is that? http://www.epochconverter.com/ It says you add on the number of seconds since 1/1/970 not ms. – Jamie R Rytlewski Jun 05 '14 at 17:51
-
If you are going from ms you obvious want `AddMillis` and if you are starting from seconds you obvious want `AddSeconds`. – jamesSampica Jul 17 '14 at 13:28
-
I had the same problem I was keep getting out of range when using seconds. The unix time I was trying to convert was in milliseconds. I thought it was in seconds. I guess some unix time is measured in miliseconds. – DoodleKana May 13 '15 at 17:47
-
Unix Time is usually expressed in seconds, but 0.001 is a valid number of seconds (= 1 ms). When in doubt, just use the maximum possible precision. – Him Jul 10 '17 at 16:56
The Unix epoch is the number of seconds that have elapsed since January 1, 1970 at midnight UTC time minus the leap seconds. This means that at midnight of January 1, 1970, Unix time was 0. The Unix epoch is also called Unix time, POSIX time, or Unix timestamp.
With .Net Framework 4.6 or higher Use the method DateTimeOffset.ToUnixTimeMilliseconds() It returns the number of milliseconds that have elapsed since 1970-01-01T00:00:00.000Z
.
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
It's well documented here DateTimeOffset.ToUnixTimeMilliseconds
To get the EPOCH with seconds only you may use
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
and convert the Epoch
to DateTime
with the following method
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
But Since
On systems where the representation of Unix time is as a signed 32-bit number, the representation will end after 231 - 1 seconds which will happen at 3:14:08 on 19 January 2038 UTC. This is called the Year 2038 problem where the 32-bit signed Unix time will overflow.
I suggest to save it as long not int
as EPOCH_2038_SAFE
long EPOCH_2038_SAFE =
(long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
If you are looking for more, use the following with more ticks precision
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;

- 3,644
- 1
- 27
- 40
-
3[DateTime.Ticks](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.ticks?view=netframework-4.8) - each tick is "one hundred nanoseconds", making it an extra 'thing' to remember. If omitting both `.Ticks`, one would get back a nice TimeSpan instance from the DateTime substraction. – user2864740 Jul 25 '19 at 17:21
If you want better performance you can use this version.
public const long UnixEpochTicks = 621355968000000000;
public const long TicksPerMillisecond = 10000;
public const long TicksPerSecond = TicksPerMillisecond * 1000;
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static DateTime FromUnixTimestamp(this long unixTime)
{
return new DateTime(UnixEpochTicks + unixTime * TicksPerSecond);
}
From a quick benchmark (BenchmarkDotNet) under net471 I get this number:
Method | Mean | Error | StdDev | Scaled |
-------------- |---------:|----------:|----------:|-------:|
LukeH | 5.897 ns | 0.0897 ns | 0.0795 ns | 1.00 |
MyCustom | 3.176 ns | 0.0573 ns | 0.0536 ns | 0.54 |
2x faster against LukeH's version (if the performance mater)
This is similar to how DateTime internally work.

- 6,634
- 4
- 38
- 90

- 484
- 4
- 10
// convert datetime to unix epoch seconds
public static long ToUnixTime(DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds);
}
Should use ToUniversalTime() for the DateTime object.

- 2,318
- 2
- 22
- 16
currently you can simply use
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
it will be returned as a 64-bits long

- 239
- 3
- 7
I use following extension methods for epoch conversion
public static int GetEpochSeconds(this DateTime date)
{
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
return (int)t.TotalSeconds;
}
public static DateTime FromEpochSeconds(this DateTime date, long EpochSeconds)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(EpochSeconds);
}

- 400
- 5
- 12
Since .Net 4.6 and above please use
DateTimeOffset.Now.ToUnixTimeSeconds()

- 15,207
- 5
- 21
- 44

- 271
- 1
- 3
- 11
To not worry about using milliseconds or seconds just do:
public static DateTime _ToDateTime(this long unixEpochTime)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var date = epoch.AddMilliseconds(unixEpochTime);
if (date.Year > 1972)
return date;
return epoch.AddSeconds(unixEpochTime);
}
If epoch time is in seconds then there is no way you can pass year 1972 adding milliseconds.

- 34,064
- 78
- 298
- 470
If you are not using 4.6, this may help Source: System.IdentityModel.Tokens
/// <summary>
/// DateTime as UTV for UnixEpoch
/// </summary>
public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// Per JWT spec:
/// Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time.
/// </summary>
/// <param name="datetime">The DateTime to convert to seconds.</param>
/// <remarks>if dateTimeUtc less than UnixEpoch, return 0</remarks>
/// <returns>the number of seconds since Unix Epoch.</returns>
public static long GetIntDate(DateTime datetime)
{
DateTime dateTimeUtc = datetime;
if (datetime.Kind != DateTimeKind.Utc)
{
dateTimeUtc = datetime.ToUniversalTime();
}
if (dateTimeUtc.ToUniversalTime() <= UnixEpoch)
{
return 0;
}
return (long)(dateTimeUtc - UnixEpoch).TotalSeconds;
}

- 824
- 7
- 15
-
1Thanks for example from JWT. By the way, to use it, just use: `using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);` – liquide Aug 06 '19 at 15:38
In case you need to convert a timeval struct (seconds, microseconds) containing UNIX time
to DateTime
without losing precision, this is how:
DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private DateTime UnixTimeToDateTime(Timeval unixTime)
{
return _epochTime.AddTicks(
unixTime.Seconds * TimeSpan.TicksPerSecond +
unixTime.Microseconds * TimeSpan.TicksPerMillisecond/1000);
}

- 113,022
- 33
- 324
- 344
Here is my solution:
public long GetTime()
{
DateTime dtCurTime = DateTime.Now.ToUniversalTime();
DateTime dtEpochStartTime = Convert.ToDateTime("1/1/1970 0:00:00 AM");
TimeSpan ts = dtCurTime.Subtract(dtEpochStartTime);
double epochtime;
epochtime = ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds);
return Convert.ToInt64(epochtime);
}
-
8
-
1To expand on the previous comment, here's a short video that explains why time is complicated and why you shouldn't try doing it yourself: https://www.youtube.com/watch?v=-5wpm-gesOY – vmrob Jul 19 '15 at 18:31