Ulysses
Ulysses

Reputation: 6015

Time Zone in timeStamp param to Date constructor leads to 'invalid date' error

While trying to create date feeding a timeStamp to the Date() constructor (snippet below) - the first call works but the second call throws ('invalid date') error whenever a time zone is specified - how to correct this?

var date1 = new Date('Dec 17, 1995 03:24:00 AM EST'); //<---- THIS WORKS!!!
console.log(date1)
// Sun Dec 17 1995 03:24:00 GMT...

var date2 = new Date('1995-12-17T03:24:00 EST'); //<---- THIS DOES NOT WORK!!!
console.log(date2)

Output:

> Sun Dec 17 1995 13:54:00 GMT+0530 (India Standard Time)
> Invalid Date
> false
> NaN

This is not a duplication question as initialization from timeStamp fed to constructor is requested as against the suggested duplicate question.

Upvotes: 0

Views: 724

Answers (2)

Ulysses
Ulysses

Reputation: 6015

This code doesn't solve the problem for directly timestamping time-zones but provides an alternative to supporting preferred time-zones as well creating js acceptable time-stamps converting numerical month to month name dynamically. This is just crude solution open to suggestions.

function getTZId(zone) {
    var retId = zone;
    if (zone) {
        //placeholder to maintain / add new zone id patterns
        //a word of caution: some timezones are not supported so offset will be required
        var zoneIds = {
            'EST':[/ET/,/EST/,/EAST/,/OTT/],
            'UTC+5:30':[/IST/,/IND/,/GURG/],
            'CST':[/CENTR/,/NA/],
            'UTC':[/UTC/,/GMT/,/ZULU/,/Z/,/GREEN/]
        }
        //default zone id
        var defZnId = 'UTC';
        var fnd = _.findIndex (
            Object.keys( zoneIds ),
            //lookup all zone id's for a match among respective zone patterns till first matching zone id is found
            znId => {
                return (                
                    _.findIndex (
                        zoneIds[znId],
                        //match each zone pattern for this zone id till the first match is found
                        znPtrn=>{
                            return znPtrn.test( zone.toUpperCase() )
                        }
                    ) !== -1
                )
            }
        );
        //return zone id if matching zone id found else return default zone id: 'UTC'
        retId = (fnd!==-1?Object.keys( zoneIds )[fnd]:defZnId);
    }
    return retId;
}

var yr = "2018", mn = "2", dy = "28", hr = "14", min = "05";
var timezone = "EST";

//get date components for current timezone like month names etc
var tmpDt = (new Date(`${yr}-${mn}-${dy}T${hr}:${min}`)).toDateString().match(/^([A-Za-z]+)\s+([A-Za-z]+)\s+(\d+)\s+(\d+)$/i);

//use above code to create appropriate time stamp
return (new Date(`${tmpDt[2]} ${tmpDt[3]}, ${yr} ${hr}:${min}:00 ${getTZId(tmZoneStr)}`));

Upvotes: 0

Ridham Tarpara
Ridham Tarpara

Reputation: 6160

You are providing the wrong format in the argument.

new Date('1995-12-17T03:24:00 EST');

What's wrong

The format you are provideing in date constructor is standard called as ISO_8601. According to standard you can not provide timezone offset like you did.

Correct way

If the time being described is one hour ahead of UTC (such as the time in Berlin during the winter), the zone designator would be "+01:00";

new Date('1995-12-17T03:24:00+01:00');

If the time being described is one hour behind of UTC, the zone designator would be "+01:00";

new Date('1995-12-17T03:24:00-01:00');

Following all refer to same time "18:30Z", "22:30+04", "1130−0700", and "15:00−03:30".

Upvotes: 2

Related Questions