Chrome interprets ISO time without Z as UTC; Problem with C #

Run this jsfiddle: http://jsfiddle.net/E9gq9/7/ in Chrome, FF and IE, and you will get:

Chrome:

Chrome http://images.devs-on.net/Image/vBTz86J0f4o8zlL3-Region.png

Firefox:

Firefox http://images.devs-on.net/Image/aNPxNPUpltyjVpSX-Region.png

IE:

IE http://images.devs-on.net/Image/WXLM5Ev1Viq4ecFq-Region.png

Safari:

Safari http://images.devs-on.net/Image/AEcyUouX04k2yIPo-Region.png

ISO 8601 does not talk about how to interpret a string without a trailing code.

Our server (ASP.NET MVC4) pulls UTC time from our database as DateTime and simply stuffs them in JSON. As you can see, because of this, we get inconsistent results in the browser.

Should we just add Z to them on the server side?

+8
javascript datetime utc
source share
4 answers

Chrome interprets ISO time without Z as UTC; Problem with C #

What is right is Firefox and IE, which are wrong.

While the article you are linking really says what it means when there is no Z ("If UTC communication information is not specified with a temporary representation, the time is considered local."), The more important thing is that the ECMAScript5 specification says it is clear that no time zone information means Z :

The offset value for the missing time zone is "Z".

Yes, I would probably make sure it has Z on it, as this gives you consistent results.

+10
source share

At the end of the day, the problem that I encounter in this application can be fixed if my server always sends DateTime client objects in a format that all browsers work correctly.

This means that there should be a β€œZ” at the end. It turns out the ASP.NET MVC4 Json serializer is based on Json.NET, but it is not enabled by default. The default value for DateTimeZoneHandling looks like RoundtripKind , and this does not output the values ​​with Z on them, even if DateTime.Kind == Utc , which is very annoying.

So it seems that the fix sets the way that Json.NET handles time zones before DateTimeZoneHandling.Utc :

 var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; // Force Utc formatting ('Z' at end). json.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; 

Now everything from my server to the browser is formatted as ISO-8601 with a β€œZ” at the end. And all the browsers I tested do it right.

+5
source share

I ran into this problem, and interpreting the date with the local time zone made a lot more sense than switching to β€œZ”, at least for my application. I created this function to add local time zone information when it is not in the ISO date. This can be used instead of the new Date (). Partly arises from this answer: How can ISO 8601 format a date with a timezone offset in JavaScript?

 parseDate = function (/*String*/ d) { if (d.search(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/) == 0) { var pad = function (num) { norm = Math.abs(Math.floor(num)); return (norm < 10 ? '0' : '') + norm; }, tzo = -(new Date(d)).getTimezoneOffset(), sign = tzo >= 0 ? '+' : '-'; return new Date(d + sign + pad(tzo / 60) + ':' + pad(tzo % 60)); } else { return new Date(d); } } 
+2
source share

David Hammond's answer is great, but it doesn't play all the tricks; so this is a modified version:

  • allows fractional part in date / time string
  • allows you to add optional seconds to a date / time string
  • considers daylight saving time
 appendTimezone = function (/*String*/ d) { // check for ISO 8601 date-time string (seconds and fractional part are optional) if (d.search(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1-3})?)?$/) == 0) { var pad = function (num) { norm = Math.abs(Math.floor(num)); return (norm < 10 ? '0' : '') + norm; }, tzo = -new Date(d).getTimezoneOffset(), sign = tzo >= 0 ? '+' : '-'; var adjusted = d + sign + pad(tzo / 60) + ':' + pad(tzo % 60); // check whether timezone offsets are equal; // if not then the specified date is just within the hour when the clock // has been turned forward or back if (-new Date(adjusted).getTimezoneOffset() != tzo) { // re-adjust tzo -= 60; adjusted = d + sign + pad(tzo / 60) + ':' + pad(tzo % 60); } return adjusted; } else { return d; } } parseDate = function (/*String*/ d) { return new Date(appendTimezone(d)); } 
0
source share

All Articles