37

I am trying to get the GMT in unix time. I use the following code:


        public static long GetGMTInMS()
        {
            var unixTime = DateTime.Now.ToUniversalTime() -
                new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            return (long)unixTime.TotalMilliseconds;
        }

To then convert the unix time back to a DatTime object, I use this:


        public static DateTime UnixTimeStampToDateTime(double unixTimeStamp)
        {
            System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            dtDateTime = dtDateTime.AddMilliseconds(unixTimeStamp).ToLocalTime();
            return dtDateTime;
        }

When I run it, the GetGMTInMS() 1320249196267. When I pass it to UnixTimeStampToDateTime() I get {11/2/2011 11:53:16 AM}

Which is fine. That is the correct time fro when I ran my code. The issue I have is when I try and put 1320249196267 into an unix time converter, such as this, it returns the totally wrong time.

The other issue, is i am in the eastern time zone. This returned the time in my time zone. Is this something that the DateTime object handles or am I not getting the GMT.

user489041
  • 27,916
  • 55
  • 135
  • 204

2 Answers2

134

"Unix timestamp" means seconds since the epoch in most situations rather than milliseconds... be careful! However, things like Java use "milliseconds since the epoch" which may be what you actually care about - despite the tool you showed. It really depends on what you need.

Additionally, you shouldn't be doing anything with local time. Stick to universal time throughout.

I would have:

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

public static long GetCurrentUnixTimestampMillis()
{
    return (long) (DateTime.UtcNow - UnixEpoch).TotalMilliseconds;
}

public static DateTime DateTimeFromUnixTimestampMillis(long millis)
{
    return UnixEpoch.AddMilliseconds(millis);
}

public static long GetCurrentUnixTimestampSeconds()
{
    return (long) (DateTime.UtcNow - UnixEpoch).TotalSeconds;
}

public static DateTime DateTimeFromUnixTimestampSeconds(long seconds)
{
    return UnixEpoch.AddSeconds(seconds);
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Should the returned type be `ulong` instead of long, as UNIX timestamps cannot be negative? – Erik Schierboom Apr 02 '13 at 09:21
  • 9
    @ErikSchierboom: Well that depends - there are plenty of scenarios where "seconds since the Unix epoch" or "milliseconds since the Unix epoch" are used where they *can* be negative. Given that `long.MaxValue` seconds is ever such a long way away, I think it makes more sense to be flexible and accept negative values for times before 1970. – Jon Skeet Apr 02 '13 at 09:24
  • 3
    Recently you can now use DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() – code5 Jun 12 '18 at 15:19
5

UNIX time is seconds since 1/1/1970, not milliseconds. Change the code to use seconds rather than milliseconds and it should work,

arx
  • 16,686
  • 2
  • 44
  • 61
  • I see no reason for the use of local time *anywhere* in the OP's code. .. I don't *think* it breaks anything in this case, but it makes the code harder to verify. – Jon Skeet Nov 02 '11 at 16:08