How do you convert epoch time in C#?
Asked Answered
T

15

493

How do you convert Unix epoch time into real time in C#? (Epoch beginning 1/1/1970)

Tannen answered 21/5, 2010 at 15:52 Comment(3)
Unless 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.Durston
Time since epoch is the number of seconds since January 1, 1970 UTC.Riel
Dup, with other answers: https://mcmap.net/q/75390/-how-can-i-convert-a-datetime-to-the-number-of-seconds-since-1970/712526Pineapple
D
759

UPDATE 2024

In .NET core (>= 2.1)

DateTime.UnixEpoch.AddSeconds(epochSeconds)
DateTime.UnixEpoch.AddMilliseconds(epochMilliseconds)

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);
}
Dorsad answered 21/5, 2010 at 16:4 Comment(5)
To 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). epochconverter.com will also let you check your conversion results.Dissepiment
You 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.Messily
@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.Kashmir
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 crashBeseem
What about leap seconds??Saturate
V
246

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;
Vigor answered 6/10, 2014 at 22:38 Comment(5)
I am getting 'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds' How would I go about resolving this?Nonetheless
@HappyBird Are you on .NET 4.6 or above?Vigor
The same thing - 4.7.2 and have no FromUnixTimeMilliseconds method for DateTimeOffset...Oligochaete
I got it. I don't need to create new object. It's a static method.Oligochaete
I found the default values a bit confusing at first glance. Bc 1000 is the factor to convert from millis to seconds.Celtuce
T
191

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;
}
Teodoro answered 21/10, 2011 at 3:44 Comment(5)
ToUnixTime only works correctly if date is in Utc. Either add a check, or convert it. (Personally I prefer the check)Dialectic
Just spent the past hour figuring out why this doesnt work. You need to work in milliseconds not seconds!!!Foreword
@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)...Kashmir
Thanks 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.Defiance
You should use AddMilliseconds and you should use Double NOT Float. Otherwise you'll end up with a wrong time.Tracheostomy
J
25

You actually want to AddMilliseconds(milliseconds), not seconds. Adding seconds will give you an out of range exception.

Jockstrap answered 19/3, 2012 at 22:2 Comment(4)
Why is that? epochconverter.com It says you add on the number of seconds since 1/1/970 not ms.Vilhelmina
If you are going from ms you obvious want AddMillis and if you are starting from seconds you obvious want AddSeconds.Ekaterina
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.Decant
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.Robespierre
V
23

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;
Vc answered 29/5, 2019 at 15:13 Comment(1)
DateTime.Ticks - 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.Ossuary
U
14

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.

Unbowed answered 28/1, 2018 at 17:1 Comment(0)
R
9
// 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.

Romanesque answered 13/3, 2012 at 6:36 Comment(0)
A
7

currently you can simply use

DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()

it will be returned as a 64-bits long

Atop answered 18/6, 2020 at 13:26 Comment(0)
M
5

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);

    }
Mixon answered 31/10, 2015 at 6:32 Comment(0)
C
3

Since .Net 4.6 and above please use

DateTimeOffset.Now.ToUnixTimeSeconds()
Comedienne answered 11/10, 2019 at 10:32 Comment(0)
B
2

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.

Beseem answered 16/10, 2019 at 18:45 Comment(0)
A
1

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;
    }    
Attack answered 14/10, 2015 at 5:0 Comment(1)
Thanks for example from JWT. By the way, to use it, just use: using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);Marlyn
V
0

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);
}
Vigor answered 6/6, 2014 at 0:11 Comment(0)
C
0

DateTime from epoch time (from seconds).

DateTime dateTime = EpochTime.DateTime(unixEpoch)

Gets the number of seconds from 1970-01-01T0:0:0Z

long unixEpoch = EpochTime.GetIntDate(dateTime);

Namespace: Microsoft.IdentityModel.Tokens

Chrysolite answered 8/10, 2023 at 19:5 Comment(0)
K
-5

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);
}
Kasher answered 18/7, 2012 at 10:13 Comment(2)
does this account for leap years and leap seconds etc?Zampino
To 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: youtube.com/watch?v=-5wpm-gesOYStrobila

© 2022 - 2024 — McMap. All rights reserved.