9

I want to get the current UTC date in JavaScript, but display it in the local date format (like Date.toLocaleDateString() does).

I first tried to just get the current UTC Date with Date.toUTCString() but that doesn't actually print out in the local format.

I then tried using the options configuration in toLocaleDateString(), but that just printed the local date and not the UTC date in the local format. e.g. new Date().toLocaleDateString(options = {timeZone: "UTC"})

I then tried formatting using Intl.DateTimeFormat(), but that just gives the same results as Date.toLocaleDateString() does.

If there was a way to get the locale format then I'd be happy to use that format to format the UTC Date, but as far as I can tell there is none.

For example, given the new Date("Sat, 30 Mar 2019 00:27:19 GMT"), In the US, I should print out "3/30/2019", in Europe I should print out "30/3/2019", and so on, for every supported locale.

However, new Date("Sat, 30 Mar 2019 00:27:19 GMT").toLocaleDateString(options = {timeZone: "UTC"}) will print out "3/29/2019" instead.

Masoud Keshavarz
  • 2,166
  • 9
  • 36
  • 48
AndersonHappens
  • 507
  • 1
  • 4
  • 16
  • Possible duplicate of [Where can I find documentation on formatting a date in JavaScript?](https://stackoverflow.com/questions/1056728/where-can-i-find-documentation-on-formatting-a-date-in-javascript) – Heretic Monkey Mar 30 '19 at 01:19
  • @HereticMonkey, I was asking how to display the current UTC date in the local format. How is that a duplicate of asking where the documentation is on formatting a date? My question is not addressed anywhere in the post you linked to. Can you clarify? – AndersonHappens Mar 30 '19 at 01:51
  • 1
    I'm not sure I understand your intention. It sounds like you want to show the current time to the user, for their locale (after all, that's _the same_ as getting the current UTC time, and then converting it to someone's locale). So why not just ... do that? Client side, `(new Date()).toLocaleString()` and we're done, aren't we? – Mike 'Pomax' Kamermans Mar 30 '19 at 04:20
  • The answers to that question cover practically every conceivable way of formatting a `Date` object. I'm not sure how you couldn't find an answer there. – Heretic Monkey Mar 30 '19 at 12:46
  • @Mike'Pomax'Kamermans The idea is to get the actual date according to UTC, but display that in their local country or areas format. Not get the date in their time zone and display that. I already made an answer below that basically does what I want. – AndersonHappens Mar 30 '19 at 20:31
  • Get the actual date _where_? Because their computer already knows what the actual date is, provided their clock is synced, which is 99.999% of cases will be true (windows, macos, etc. all sync their clocks using ntp servers). This seems like trying to solve a problem that doesn't exist: people's clocks will be perfectly fine, just use `(new Date()).toLocaleString()` and you're already done. – Mike 'Pomax' Kamermans Mar 30 '19 at 22:00
  • Very good question. This is the exact issue I was willing to resolve right now. – J. Bruni Apr 08 '19 at 09:52

7 Answers7

9

I also wanted to display a date using localized string settings, like toLocaleDateString() does, but using the date's UTC value, instead of the local time zone.

For example:

Localized UTC date problem

I do want the localized string format, but I also want the UTC value instead of the local time zone value. The desired output in this example would be 4/3/2019, instead of 4/2/2019.


I acknowledged @AndersonHappens suggestion, but I have not used it. Here is what I did, instead:

There is a getTimezoneOffset() function, which provides the local time zone offset.

We can use this function result and create a new Date, applying the diff. Then, we can use toLocaleDateString() directly, as usual, to get the date in localized string format:

Localized UTC date solution

The solution as a function could be like this:

function toLocaleUTCDateString(date, locales, options) {
    const timeDiff = date.getTimezoneOffset() * 60000;
    const adjustedDate = new Date(date.valueOf() + timeDiff);
    return adjustedDate.toLocaleDateString(locales, options);
}
J. Bruni
  • 20,322
  • 12
  • 75
  • 92
5

You almost got it right - the timeZone option is available in the second argument. The first argument to toLocaleDateString is for the locales.

This example from your question works when options are the second argument (and is much simpler than other answers):

const usLocale = 'en-US'
new Date('Sat, 30 Mar 2019 00:27:19 GMT').toLocaleDateString(usLocale, {
  timeZone: 'UTC',
})
// '3/30/2019'

const ukLocale = 'en-GB'
new Date('Sat, 30 Mar 2019 00:27:19 GMT').toLocaleDateString(ukLocale, {
  timeZone: 'UTC',
})
// '30/03/2019'

Andrew Marquez
  • 150
  • 2
  • 6
3

Given a date, you can get the locale format with new Intl.DateTimeFormat(). You can then use formatToParts in order to get the formatting of the date and each specific component.

Following the example in the formatToParts documentation, I created the following method to get the UTC date in the locale string.

function toLocaleUTCDateString(date) {
  let formatter = new Intl.DateTimeFormat();
  return formatter.formatToParts(date).map(({type, value}) => { 
    switch (type) {
      case 'day': return date.getUTCDate();
      case 'hour': return date.getUTCHours();
      case 'minute': return date.getUTCMinutes();
      case 'month': return date.getUTCMonth() + 1;
      case 'second': return date.getUTCSeconds();
      case 'timeZoneName': return "UTC";
      case 'year': return date.getUTCFullYear();
      default : return value; 
    } 
  }).reduce((string, part) => string + part);
}

Do note however that this method does not remember number versus string formatting. For example, if you want to display the month of March as "March" (or the specific language month string), and not as the number 3, you would have to figure out how to do that yourself. It also doesn't handle discrepancies in weekdays, so if the local date is "Friday" and the UTC Date is "Saturday", you would have to figure that out separately as well.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
AndersonHappens
  • 507
  • 1
  • 4
  • 16
1
var dateToPrint = new Date(Date.UTC(2020, 3, 23, 15, 0, 0));

new Date(
  dateToPrint.getUTCFullYear(),
  dateToPrint.getUTCMonth(),
  dateToPrint.getUTCDate(),
  dateToPrint.getUTCHours(),
  dateToPrint.getUTCMinutes(),
  dateToPrint.getUTCSeconds()
).toLocaleString('es-ES')

see image

Mario Nikolaus
  • 2,346
  • 1
  • 21
  • 28
Rafael
  • 11
  • 1
1

Inside the toLocaleDateString you can pass options. There is an option name TimeZone. You have to set it to 'UTC'

const dateToParse = new Date()
dateToParse.toLocaleDateString(locate, { timeZone: 'UTC' })
Dante Nuñez
  • 439
  • 4
  • 7
0

Check out Intl.DateTimeFormat on MDN!

Using it is as simple as

// do this once in a central library file
const formatter = new Intl.DateTimeFormat('en', {
  timeZone: 'UTC',
  timeZoneName: 'short',
  month: 'short',
  day: '2-digit',
  hour12: false,
  hour: '2-digit',
  minute: '2-digit',
})

// reuse anywhere for consistency
const myDate = new Date(
  'Thu Feb 10 2022 12:50:14 GMT+0100'
)

formatter.format(myDate) === 'Feb 10, 11:50 UTC' // true

Open your console, copy-paste the code and start playing!

Again, Intl.DateTimeFormat on MDN.

Enjoy!

-1

toLocaleString receives some parameters, the first parameter is the locale. To solve your issue specifically, you need to understand that UTC is not a locale. What you could to to accomplish what you want is to pass either 'en-US' for 3/29/2019 and 'en-GB' for 29/03/2019 hope that helps!

Jose Munoz
  • 558
  • 2
  • 12