Parse date without timezone javascript

I ran into the same problem and then remembered something wonky about a legacy project I was working on and how they handled this issue. I didn't understand it at the time and didn't really care until I ran into the problem myself

var date = '2014-01-02T00:00:00.000Z'
date = date.substring(0,10).split('-')
date = date[1] + '-' + date[2] + '-' + date[0]

new Date(date) #Thu Jan 02 2014 00:00:00 GMT-0600

For whatever reason passing the date in as "01-02-2014" sets the timezone to zero and ignores the user's timezone. This may be a fluke in the Date class but it existed some time ago and exists today. And it seems to work cross-browser. Try it for yourself.

This code is implemented in a global project where timezones matter a lot but the person looking at the date did not care about the exact moment it was introduced.


The date is parsed correctly, it's just toString that converts it to your local timezone:

let s = "2005-07-08T11:22:33+0000";
let d = new Date(Date.parse(s));

// this logs for me 
// "Fri Jul 08 2005 13:22:33 GMT+0200 (Central European Summer Time)" 
// and something else for you

console.log(d.toString()) 

// this logs
// Fri, 08 Jul 2005 11:22:33 GMT
// for everyone

console.log(d.toUTCString())

Javascript Date object are timestamps - they merely contain a number of milliseconds since the epoch. There is no timezone info in a Date object. Which calendar date (day, minutes, seconds) this timestamp represents is a matter of the interpretation (one of to...String methods).

The above example shows that the date is being parsed correctly - that is, it actually contains an amount of milliseconds corresponding to "2005-07-08T11:22:33" in GMT.


Since it is really a formatting issue when displaying the date (e.g. displays in local time), I like to use the new(ish) Intl.DateTimeFormat object to perform the formatting as it is more explicit and provides more output options:

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };

const dateFormatter = new Intl.DateTimeFormat('en-US', dateOptions);
const dateAsFormattedString = dateFormatter.format(new Date('2019-06-01T00:00:00.000+00:00'));

console.log(dateAsFormattedString) // "June 1, 2019"

As shown, by setting the timeZone to 'UTC' it will not perform local conversions. As a bonus, it also allows you to create more polished outputs. You can read more about the Intl.DateTimeFormat object in Mozilla - Intl.DateTimeFormat.

The same functionality can be achieved without creating a new Intl.DateTimeFormat object. Simply pass the locale and date options directly into the toLocaleDateString() function.

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };
const myDate = new Date('2019-06-01T00:00:00.000+00:00');
myDate.toLocaleDateString('en-US', dateOptions); // "June 1, 2019"

I have the same issue. I get a date as a String, for example: '2016-08-25T00:00:00', but I need to have Date object with correct time. To convert String into object, I use getTimezoneOffset:

var date = new Date('2016-08-25T00:00:00')
var userTimezoneOffset = date.getTimezoneOffset() * 60000;
new Date(date.getTime() - userTimezoneOffset);

getTimezoneOffset() will return ether negative or positive value. This must be subtracted to work in every location in world.