Reputation: 2996
I am aware that Unix Timestamp are UTC in nature (misleading, this is not true, new Date()
will always be on the browser/server timezone, and .getTime()
reflects that).
How come when converting to a C# DateTime is is not UTC.
I've converted the date August, 9 2092 to timespamp in seconds (3869074800),
new Date('August, 9 2092').getTime()/1000
or https://codepen.io/pnmcosta/pen/rpvjVp
But when converting to a C# date, it's not UTC (8/8/2092 11:00:00 PM)? Even though the EPOCH has been created as UTC:
using System;
public class Program
{
public readonly static DateTime EPOCH_UNIX = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private readonly static double MaxUnixSeconds = (DateTime.MaxValue.ToUniversalTime() - EPOCH_UNIX).TotalSeconds;
public static void Main()
{
Console.WriteLine(FromUnixTimeStamp(3869074800));
}
public static DateTime FromUnixTimeStamp(long value)
{
return value > MaxUnixSeconds ? EPOCH_UNIX.AddMilliseconds(value) : EPOCH_UNIX.AddSeconds(value);
}
}
or https://dotnetfiddle.net/ERySea
How best to handle this scenario, bearing in mind that time is not of importance, but the day should be correct?
EDIT 2
Think I may have hacked the date to figure out the offset (updated https://dotnetfiddle.net/ERySea) to:
using System;
public class Program
{
public readonly static DateTime EPOCH_UNIX = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private readonly static long MaxUnixSeconds = (long)(DateTime.MaxValue.ToUniversalTime() - EPOCH_UNIX).TotalSeconds;
public static void Main()
{
// date with DST (Daylight savings time), e.g. 08/09/2092 (DD/MM/yyyy)
// is stored as, e.g. 3869074800 seconds, from EPOCH_UNIX
// instead of 3869078400 (UTC, without offsets) as it should be!
DateTime dt = FromUnixTimeStamp(3869074800);
Console.WriteLine("Date: {0:dd MMM yyyy HH:mm}", dt);
// fix DST offset
if (dt.Hour != 0)
{
int offset = 24 - dt.Hour;
dt = dt.AddHours(offset);
Console.WriteLine("Offset: {0}", offset);
}
// fix century (if date of birth)
if (dt.Year >= DateTime.UtcNow.Year)
dt = dt.AddYears(-100);
Console.WriteLine("Fixed Date: {0:dd MMM yyyy HH:mm}", dt);
}
public static DateTime FromUnixTimeStamp(long value)
{
return value > MaxUnixSeconds ? EPOCH_UNIX.AddMilliseconds(value) : EPOCH_UNIX.AddSeconds(value);
}
}
Upvotes: 2
Views: 2580
Reputation: 13060
The problem is JavaScript not C#, or more correctly your premise what new Date('August, 9 2092').getTime()/1000
represents.
JavaScript will create a new Date as being in local time zone not UTC. So
new Date('August, 9 2092')
is actually
Sat Aug 09 2092 00:00:00 GMT+0100 (GMT Daylight Time)
Notice the offset? This is actually Fri Aug 08 2092 23:00:00 UTC+0000
so the epoch you get from JavaScript is not what you intended.
You should subtract the timezone offset (in minutes multiplied by 60) to get UTC though.
var date = new Date('August, 9 2092');
var timestamp = date.getTime()/1000 - date.getTimezoneOffset()*60;
// timestamp == 3869078400
EDIT
Rather than fudging the calculation, you'd be better off assuming the timestamp is local...
Change
public readonly static DateTime EPOCH_UNIX = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
to
public readonly static DateTime EPOCH_UNIX = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local);
At least then the result is 08 Aug 2092 23:00 Local
.
Upvotes: 1
Reputation: 145
According to https://www.epochconverter.com/ the UNIX timestamp of 3869074800 is 8/8/2092 11:00:00 PM, so C# is correctly displaying it in GMT. UTC and GMT are... not the same, but for the purposes of a human reading it it's accurate to say that you can treat them as the same.
Your problem lies in how you got the UNIX timestamp of 3869074800.
Upvotes: 1