Losing time when converting from Epoch time

I am getting the time in EpochTime. When I convert to local time using the funciton, I am losing 1 hour. I am not sure if the calculation is wrong. can you review it.

       private DateTime ConvertUnixEpochTime(long seconds)
   {

       DateTime Fecha = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
       Debug.WriteLine("Converted time in gmt   " + Fecha.AddSeconds(seconds));
       Debug.WriteLine("Converted time in local time  " + Fecha.ToLocalTime().AddSeconds(seconds));
       Debug.WriteLine("EpochTime" + seconds);
       Debug.WriteLine("current local time " + DateTime.Now);
       Debug.WriteLine("current time in gmt " + DateTime.Now.ToUniversalTime());

       return Fecha.ToLocalTime().AddSeconds(seconds);

   }

Here is a extract of the debug.write statments.

TickString Tick value: 1401395106 Tick Type: LAST_TIMESTAMP // this is the input
Converted time in gmt   2014-05-29 8:25:06 PM  // this is the converted tiem in GMT
Converted time in local time  2014-05-29 3:25:06 PM // this is the converted time to local EST Timezone
EpochTime1401395106
current local time 2014-05-29 4:31:33 PM // Current local time in EST
current time in gmt 2014-05-29 8:31:33 PM // Current local Time in GMT
Jon Skeet
people
quotationmark

The problem is that you're adding seconds after converting to local time.

In other words, you're converting the Unix epoch to EST, then adding 1401395106 seconds.

Insteead, you should be adding 1401395106 seconds to the Unix epoch, and then converting to local time - which is EDT, not EST. It's important to understand the difference - you're in Eastern Time, which is currently observing EDT, or UTC-4. DateTime.AddSeconds doesn't take any time zone transitions into account - it simply adds the seconds in a naive fashion. That's where the hour is being lost - because you're converting it in EST (UTC-5) but ending up on a date which is in EDT.

So here's code which should work for you:

DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Debug.WriteLine("Converted time in gmt   " + epoch.AddSeconds(seconds));
Debug.WriteLine("Converted time in local time  " + 
                epoch.AddSeconds(seconds).ToLocalTime());

Personally I'd use Noda Time though, which makes it harder to make this sort of error:

Instant instant = Instant.FromSecondsSinceUnixEpoch(seconds);
// Or use DateTimeZoneProviders.Bcl.GetSystemDefault(), maybe...
DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/New_York"];
ZonedDateTime zoned = instant.InZone(zone);

people

See more on this question at Stackoverflow