Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assume local time zone when parsing ISO 8601 date string?

Tags:

javascript

I have a ISO date string as below

 var startTimeISOString = "2013-03-10T02:00:00Z"; 

when I convert it to date object in javascript using below code, it returns

var startTimeDate = new Date(startTimeISOString); 

output is

Date {Sun Mar 10 2013 07:30:00 GMT+0530 (India Standard Time)} 

It sure converts the ISOString to date but it converts to local time since new Date() is client dependent. How to just convert iso date time string to date and time but not to local date-time..?

Thanks

like image 455
CrazyNooB Avatar asked Mar 20 '13 06:03

CrazyNooB


People also ask

How do I set timezone in ISO 8601?

ISO 8601 represents date and time by starting with the year, followed by the month, the day, the hour, the minutes, seconds and milliseconds. For example, 2020-07-10 15:00:00.000, represents the 10th of July 2020 at 3 p.m. (in local time as there is no time zone offset specified—more on that below).

How do I convert ISO date to local time?

Use the getTime() method to convert an ISO date to a timestamp, e.g. new Date(isoStr). getTime() . The getTime method returns the number of milliseconds since the Unix Epoch and always uses UTC for time representation.

Does ISO 8601 include timezone?

Time zones in ISO 8601 are represented as local time (with the location unspecified), as UTC, or as an offset from UTC.


2 Answers

According to MDN:

Differences in assumed time zone

Given a date string of "March 7, 2014", parse() assumes a local time zone, but given an ISO format such as "2014-03-07" it will assume a time zone of UTC. Therefore Date objects produced using those strings will represent different moments in time unless the system is set with a local time zone of UTC. This means that two date strings that appear equivalent may result in two different values depending on the format of the string that is being converted (this behavior is changed in ECMAScript ed 6 so that both will be treated as local).

I have done like this and am now getting the exact time which is inside the ISO date string instead of the local time

 var startTimeISOString = "2013-03-10T02:00:00Z";   var startTime = new Date(startTimeISOString );  startTime =   new Date( startTime.getTime() + ( startTime.getTimezoneOffset() * 60000 ) ); 

This will give the same date time inside iso date string , the output here is

o/p

Date {Sun Mar 10 2013 02:00:00 GMT+0530 (India Standard Time)} 
like image 95
CrazyNooB Avatar answered Sep 23 '22 16:09

CrazyNooB


To sum up the conversation from tracevipin's post:

All Date objects are based on a time value that is milliseconds since 1970-01-01T00:00:00Z so they are UTC at their core. This is different to UNIX, which uses a value that is represents seconds since the same epoch.

The Date.prototype.toString method returns an implementation dependent string that represents the time based on the system settings and timezone offset of the client (aka local time).

If a UTC ISO8601 time string is required, the Date.prototype.toISOString method can be used. It's quite easy to write a "shim" for this methods if required.

Lastly, do not trust Date.parse to parse a string. Support for an ISO8601 format UTC string is specified in ES5, however it's not consistently implemented across browsers in use. It is much better to parse the string manually (it's not hard, there are examples on SO of how to do it) if wide browser support is required (e.g. typical web application).

Simple ISO8601 UTC time stamp parser:

function dateObjectFromUTC(s) {   s = s.split(/\D/);   return new Date(Date.UTC(+s[0], --s[1], +s[2], +s[3], +s[4], +s[5], 0)); } 

and here's a shim for toISOString:

if (typeof Date.prototype.toISOString != 'function') {    Date.prototype.toISOString = (function() {        function z(n){return (n<10? '0' : '') + n;}     function p(n){       n = n < 10? z(n) : n;       return n < 100? z(n) : n;     }          return function() {       return this.getUTCFullYear() + '-' +              z(this.getUTCMonth() + 1) + '-' +              z(this.getUTCDate()) + 'T' +              z(this.getUTCHours()) + ':' +              z(this.getUTCMinutes()) + ':' +              z(this.getUTCSeconds()) + '.' +              p(this.getUTCMilliseconds()) + 'Z';     }    }()); } 
like image 25
RobG Avatar answered Sep 21 '22 16:09

RobG