So dates are hard. Computer languages have varying success in implementing them. Take C#. If dates in C# were awesome, Jon Skeet would have had no cause to write Noda Time. I’m going to write a couple of posts about Javascript and dates, as they have caused me quite a bit of pain in recent months. Today, I will kick off with the UTC story (or lack thereof) for dates in Javascript (in the browser, anyway).
I’ll use C# to make a few comparisons in my analysis, just to highlight what is lacking.
As a really brief examination of what C# can do with dates in the context of UTC, just run the following:
var nowUTC = DateTime.UtcNow; Console.WriteLine(nowUTC.ToLongDateString() + " " + nowUTC.ToLongTimeString() + " " + nowUTC.Kind);
You’ll see that you have a DateTime value which represents the UTC time for that point in time and has a Kind of UTC (not local). A DateTime can’t tell you what timezone it is in. It just knows whether it is local or UTC. Timezones (as distinct from offsets) are political and shift with policies of governments. So it is not trivial to build them into a computer language. Note: DateTimeOffsets are a generally better struct than DateTime and contain UTC and the offset from UTC. But the point is, here we have a UTC value representing a point in time and what that time is with a +0 UTC offset.
Now, lets turn our mind to Javascript. If you were to create a Date object, using the new keyword, and write that out to the console, it would look something like this:
Fri Jan 27 2017 22:04:36 GMT+1030 (Cen. Australia Daylight Time).
You can see there’s a time offset and even a helpful addition of the name of the timezone in brackets. Yay for Javascript. Now try and create a Javascript date object that is UTC (making sure you are located in a timezone other than the Zulu timezone, of course). Here’s a hint. You can’t. Not really, anyway.
But what about all those things you read on Stackoverflow, like toISOString and methods of the Date constructor such as getUTCFullYear etc.? Yes, lets talk about that.
First, I will dispense with toISOString. Some may say that to get UTC, you can just write:
var now = new Date(); var utcnow = now.toISOString();
The fact is, toISOString returns a string representation of UTC. Not a Date object. Now, you have a string. So my assertion holds.
What about a bit of sneaky epoch shifting? Say, we wrote something like this:
var now = new Date(); var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
Have we achieved a UTC Date in Javascript yet? I would say no. If you log that Date object out to console, it would look a little like this:
Fri Jan 27 2017 11:34:36 GMT+1030 (Cen. Australia Daylight Time)
Look familiar? Sure, it’s 10.5 hours before the actual local time, but it still has the same local offset and timezone of the browser. So what happens if you now give that to a component which shifts the epoch again based on the offset? Now we are behind UTC. And we’ll have a Date object which still has the same offset. UTC has turned into a moving target, always leaping back in time by 10.5 hours.
But what about the static UTC method of the Date constructor? Something like:
var utc = Date.UTC(1900,08,18,0,0,0);
I hope you like milliseconds, because that is what that method returns. The number of milliseconds from Jan 1, 1970. And you can always pass that into a Date consructor, but you’ll just get a Date object with the browser offset and timezone.
And there’s one more scenario I’d like to cover. What if we call the Date constructor as a function? That is, without the new keyword?
var nowFromFunction = Date(); console.log(nowFromFunction);
Sorry to disappoint, but that just returns a string. The string is local time as well. So, not a Date object and not UTC.
Now, it is true that Javascript dates track UTC internally. However, that is internals and components such as various HTML 5/Javascript datepickers don’t process internals.
Thus, unless someone can prove me wrong, I am asserting that you cannot create a UTC Date object in Javascript. Not like the way you can in C#.
Here’s a plunk to play with: Date plunk.
Oh and by the way, I was wondering why I did not pick this up when I learnt Javascript. So, I went back to the source – the Flanagan book. There is not a peep in there about how dates behave in the browser, vis-a-vis always stamping them with the local timezone and offset.
As I said at the outset, Dates are hard.
0 Comments.