0

I have an application where I am calling the function Date.parse as follows:

Date.parse('2021-02-22' + ' ' + '13:00')

However, when I run the app locally and in production (AWS), this function seems to return two different results. Locally it returns 1613959200000 while in production it returns 1613998800000. Upon further investigation, 1613959200000 seems to convert to 2021-02-22 at 13:00 in Australian Eastern Daylight time, while 1613998800000 converts to 2021-02-22 at 13:00 in UTC time. Is there a way I can force Date.parse() to convert for the local timezone of the client/browser, rather than UTC? (in this case Australian Eastern Daylight time, but I'd want it to work for all timezones).

EDIT: I have tried using date objects, in order to produce a date/time object that is in sync with the local timezone, but it doesn't seem to work as shown in the code below:

var d = new Date("Mon Feb 22 2021 00:00:00 GMT+1100 (Australian Eastern Daylight Time)");

var ds = d.toString();

var e = new Date(2021,2,22,0,0)
var es = e.toString();

console.log(ds === es) //returns false for some reason
Sabo Boz
  • 1,683
  • 4
  • 13
  • 29
  • not really - I was looking for something related to Date.parse() specifically. I also tried using date objects but it doesn't seem to work (see edit in question). – Sabo Boz Jan 28 '21 at 19:13
  • `new Date(string)` uses `Date.parse(string)` under the hood. – Heretic Monkey Jan 28 '21 at 19:53
  • [Converting a string to a date in JavaScript](https://stackoverflow.com/q/5619202/215552) then. – Heretic Monkey Jan 28 '21 at 19:59
  • You should not use the built–in parser for non–standard formats, in Safari `Date.parse('2021-02-22' + ' ' + '13:00')` returns an invalid date. – RobG Jan 28 '21 at 23:48

2 Answers2

1

By the ECMAScript spec, you simply need to use a T instead of a space to separate the date and time parts.

const t = Date.parse('2021-02-22' + 'T' + '13:00');
console.log(t); // result will differ depending on local time zone

The format is described in full under the Date Time String Format. Additionally, in the docs for Date.parse it states:

... When the sss element is absent, "000" is used. When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

Thus, a combined string of 2021-02-22T13:00 will be interpreted as 2021-02-22T13:00:00.000 in the local time zone, because it is a date-time form.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • 1
    This is covered in many duplicate questions and answers, including [Why does Date.parse give incorrect results?](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) and [Converting a string to a date in JavaScript](https://stackoverflow.com/q/5619202/215552) – Heretic Monkey Jan 28 '21 at 19:55
  • @Matt Johnson-Pint - the javascript is being evaulated in ejs on the client side – Sabo Boz Jan 28 '21 at 20:10
  • using 2021-02-22T13:00 is still somehow not working - I am still getting Date.parse('2021-02-22' + 'T' + '13:00') being evaluated to 1613998800000 – Sabo Boz Jan 28 '21 at 20:12
  • Oh - wait a second. You said **ejs**. Are you using server-side rendering? If so, the code is running on the server, not the client. That would explain your results. – Matt Johnson-Pint Jan 28 '21 at 20:31
  • I used and this turned out to be UTC, but when i console.log in the console of my browser I'm getting Australia/Sydney - I'll work under the assumption it's UTC for now – Sabo Boz Jan 28 '21 at 20:46
  • @SaboBoz - I recommend opening a new question specifically with regard to EJS. I believe you are actually executing the JS code on the server instead of on the client. – Matt Johnson-Pint Jan 28 '21 at 22:10
  • `value="<%- Intl.DateTimeFormat().resolvedOptions().timeZone %>"` is running on the server, not the client. – RobG Jan 28 '21 at 23:49
-1

You can get the timezone the client/browser is in by using Date.getTimezoneOffset. This will give you the local timezone offset from UTC in minutes.

Once you got that construct the date/time string for the Date.parse() with the correct timezone offset, like for example "2011-10-10T14:48:00+09:00".

// get the local timezone offset
let offsetInMinutes = (new Date()).getTimezoneOffset();
// convert the minutes in to hours and minutes
let hours = Math.abs(offsetInMinutes / 60);
let minutes = Math.abs(offsetInMinutes % 60);
let direction = offsetInMinutes >= 0 ? '+' : '-';

// construct the date string with timezone

let yourDate = Date.parse(
               '2021-02-22' 
               + ' ' 
               + '13:00' 
               + direction 
               + hours.toString().padStart(2, '0') 
               + ':' 
               + minutes.toString().padStart(2, '0');
John Caprez
  • 393
  • 2
  • 10
  • console.log(Date.parse('2021-02-22' + 'T' + '13:00' + ':00+' + Date.getTimezoneOffset().toString())) doesn't seem to work? – Sabo Boz Jan 28 '21 at 19:49
  • There's no need to get the offset separately. Also one would have to be very careful to get the correct offset for the date and time in question - which isn't necessarily the same as the *current* offset. – Matt Johnson-Pint Jan 28 '21 at 19:51
  • getTimezoneOffset gives you the offset in minutes so you have to covert it in to hours:minutes manually. What you do above could end up in something like 00:360 for a +6h timezone – John Caprez Jan 28 '21 at 19:59
  • And don't forget that there are negative timezone as well .. – John Caprez Jan 28 '21 at 20:04
  • 1
    This creates a Catch 22 situation where you need the offset for the date and time that hasn't been parsed yet, so how do you know the offset to apply? – RobG Jan 28 '21 at 20:44
  • The original question was "to convert for the local timezone of the client/browser". Date.getTimezoneOffset() gets the local timezone offset of the client/browser. Maybe the example I added to the answer clarifies this. – John Caprez Jan 28 '21 at 20:59
  • @JohnCaprez - That's not exactly true. `getTimeZoneOffset` returns the offset of the time zone of the browser ***for that `Date` object***. In other words, `new Date().getTimeZoneOffset()` returns the *current* offset. Since there is a 1-to-N relationship between time zone and offset, one cannot assume that the current offset is the correct offset for some other date and time. Consider time zones that have DST. If DST is in effect, `getTimeZoneOffset` will reflect that. If you then apply the offset to a date where DST is *not* in effect, you'll have moved the timestamp by an hour. – Matt Johnson-Pint Jan 28 '21 at 22:06
  • @MattJohnson-Pint, yes I'm aware of that thus I think it is a more reliable way than Intl.DateTimeFormat().resolvedOptions().timeZone in figuring out what string to construct for Date.parse(). – John Caprez Jan 29 '21 at 06:22