2

I'm looking at a semi-old codebase where the following code is used to format a date in YYYY-MM-DD format according to a user's locale:

new Date('2000-01-01').toLocaleDateString(navigator.language)

However, this doesn't work in Firefox because new Date('2000-01-01') returns a datetime (time is 00:00) in UTC while toLocaleDateString uses the user's local timezone, so the above will return "December 31, 1999" for a user in the US.

What is the sane, safe way of doing this across browsers? Is it possible to do without one or more extra dependency?

beta
  • 2,380
  • 21
  • 38
  • What have you expected to see?.. It's just a matter of formatting – FieryCat Jun 22 '17 at 17:50
  • Possibly a duplicate of https://stackoverflow.com/questions/439630/how-do-you-create-a-javascript-date-object-with-a-set-timezone-without-using-a-s – Jay Buckman Jun 22 '17 at 17:52
  • I expect to see something like `January 1, 2000`. – beta Jun 22 '17 at 17:53
  • Then use: `d = new Date(); d.setUTCFullYear(2000); d.setUTCMonth(0); d.setUTCDate(1);` – FieryCat Jun 22 '17 at 17:54
  • @FieryCat: That date is still in 1999 in e.g. a US time zone (it actually changed nothing in Firefox), so `toLocaleDateString` will still print 1999. – beta Jun 22 '17 at 18:16

1 Answers1

1

If you add a timestamp to that date string it seems to be initialized with that time in the local timezone:

new Date('2000-01-01T00:00:00');

I tried this in both Chrome and Firefox and it seems to work as you want. However, creating a date with a string should be avoided as there's no guarantee it works consistently across different browsers. It's better to break the date into its parts, parse it as numeric values and initialize the date that way:

var dateParts = '2000-01-01'.split('-').map(Number);
new Date(
  dateParts[0], 
  dateParts[1] - 1, // month is base 0
  dateParts[2]
);

Update: Turns out Safari assumes UTC even if appending a timestamp to the date string, so this is one more reason to parse it and initialize the date with numeric values, as this always uses the local timezone.

Lennholm
  • 7,205
  • 1
  • 21
  • 30