Introduction
Formatting/creating dates with Javascript without timezone can be a bit tricky due to the difference between formatting in respect to a timezone or not, in this article we will demonstrate how to format/create JavaScript dates with respect to the user local timezone.
Method 1: Using Intl.DateTimeFormat.formatToParts()
The
Intl.DateTimeFormat.prototype.formatToParts()
method allows locale-aware formatting of strings produced byIntl.DateTimeFormat
formatters.
The formatToParts()
method is useful for custom formatting of date strings. It returns an Array
of objects containing the locale-specific tokens from which it possible to build custom strings while preserving the locale-specific parts.
Here’s an example how DateTimeFormat.formatToParts works:
1- Create a Date
object.
const date = new Date(2022, 11, 13);
2- Declare the shape of the formatted date parts.
const options = {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
};
Here we’re telling the Intl.DateTimeFormat that we need the weekday to be long formatted, and the year to be a numeric value, and so on…
3- Create new Intl.DateTimeFormat
instance
const dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
We will pass to Intl.DateTimeFormat
two parameters, the first one is the locale and the second is the options object we declared in step 2.
4- Call formatToParts function
const parts = dateTimeFormat.formatToParts(date);
Putting it all together, results in the following:
const date = new Date(2022, 11, 13);
const options = {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
};
const dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
const parts = dateTimeFormat.formatToParts(date);
console.log(parts);
// Expected Output 👇👇
[
{
"type": "weekday",
"value": "Tuesday"
},
{
"type": "literal",
"value": ", "
},
{
"type": "month",
"value": "12"
},
{
"type": "literal",
"value": "/"
},
{
"type": "day",
"value": "13"
},
{
"type": "literal",
"value": "/"
},
{
"type": "year",
"value": "2022"
},
{
"type": "literal",
"value": ", "
},
{
"type": "hour",
"value": "12"
},
{
"type": "literal",
"value": ":"
},
{
"type": "minute",
"value": "00"
},
{
"type": "literal",
"value": ":"
},
{
"type": "second",
"value": "00"
},
{
"type": "literal",
"value": " "
},
{
"type": "dayPeriod",
"value": "AM"
}
]
Looks Great! Now let’s add a simple functionality to build a readable formatted date based on the above output
const date = new Date(2022, 11, 13);
const options = {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
};
const dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
const parts = dateTimeFormat.formatToParts(date);
let formattedDate = '';
parts.forEach((part) => {
if (part.type === "weekday")
formattedDate+= `${part.value}, `;
if (part.type === "day")
formattedDate+= `${part.value}/`;
if (part.type === "month")
formattedDate+= `${part.value}/`;
if (part.type === "year")
formattedDate+= `${part.value}, `;
if (part.type === "hour")
formattedDate+= `${part.value}:`;
if (part.type === "minute")
formattedDate+= `${part.value}:`;
if (part.type === "second")
formattedDate+= `${part.value}`;
});
console.log(formattedDate) // Expected Output 👇👇
Tuesday, 12/13/2022, 12:00:00
Method 2: By Manipulating javascript ISO date
To apply this way, let’s:
1- Create/Get the ISO representation of the date string.
const dateStr = '2022-08-20T01:44:31.820Z'; // Note the time is 01:44,
//my time zone is 3 hours ahead of Coordinated Universal time (UTC).
2- Remove the Z
character from the end of the ISO string
.
const dateStr = '2022-08-20T01:44:31.820Z';
const result = new Date(date.toISOString().slice(0, -1)); // Removing Z character
console.log(result); // 👉️ Sat Aug 20 2022 01:44:31 GMT+0300
This shows that after passing a date string to the Javascript Date
object and by removing the Z
character we will get the same local time
But when Trying to pass the date string to the Date object while keeping the Z character, it will results in the date formatted according to Coordinated Universal time (UTC).
const dateStr = '2022-08-20T01:44:31.820Z';
const date = new Date(dateStr);
console.log(date); // 👉️ Sat Aug 20 2022 04:44:31 GMT+0300
So as a summary, If the Z
is present, the Date
is set to UTC. If the Z
is not present, it’s set to local time (this only applies if the time is provided).
The Z
at the end of the ISO string means UTC
, in other words, an offset from UTC
of zero hours, minutes and seconds.
Photo from unsplash