waffl
waffl

Reputation: 5511

Javascript - Display date time and ignore locale/timezone

I am having a bit of a nightmare working with a CMS that saves datetimes without timezones. For a wide variety of infrastructure reasons I am unable to adjust core files, I can only adjust some of the javascript of the CMS field itself, and not include external libraries (or the dayjs UTC plugin).

How it currently works:

  1. CMS Saves datetime string like so: 2020-10-29 05:00 which is missing the timezone
  2. When reloading, the dayjs parses the string 2020-10-29 05:00 as UTC and changes the time based on the browser locale.
  3. If you are using a browser that it not UTC, the time displayed will not correspond to the saved string

My hacky idea:

  1. When loading the string, get the browser's timezone
  2. Modify the string 2020-10-29 05:00 to include the browser's timezone, or offset the date object so that when it is parsed as 'local', it will display correctly

My initial thought was just to add/subtract the offset before displaying but it still didn't seem to work (I think due to getTimezoneOffset not adjusting for daylight savings?):

let date = new Date('2020-10-29 05:00')
console.log(new Date(date.setMinutes(date.getMinutes() + new Date().getTimezoneOffset())))

I suppose an alternate form of this question is: Is there a way to parse a UTC datetime string as though it were local?

Upvotes: 1

Views: 940

Answers (1)

RobG
RobG

Reputation: 147453

If the string is UTC, you should parse it as UTC and then do everything in UTC. I think the easiest way is to parse the string as UTC with your own function or library.

Also, given:

new Date('2020-10-29 05:00')

some browsers will return an invalid date (they treat it as a malformed version of the supported format YYYY-MM-DDTHH:mm:ss).

Generally, using the built–in parser is strongly discouraged because of browser inconsistencies. Also, messing with timezone offsets can also lead to difficult to find issues (like when applying the offset causes the date to cross a DST boundary).

A simple function to do the job:

function parseAsUTC(s) {
  let [y, m, d, H, M] = s.split(/\D/);
  return new Date(Date.UTC(y, m-1, d, H, M));
}

let s = '2020-10-29 05:00';
console.log(parseAsUTC(s));

Upvotes: 0

Related Questions