Raise your hand if you've ever had issues dealing with time zones, or even if you've asked, "How do I convert a Date object to another time zone in JavaScript?"
In my personal experience, this kind of requirement can become a big problem for developers if the date-handling-related concepts are not clearly understood, or the right tools are not used.
Using Dates and Time Zones in JavaScript
Let's suppose you have a date representation from an external API, and you need to convert the date to any desired time zone.
The best option for this is using a representation that meets the ISO 8601 standard. As an example of this, we can set a date like 2021/06/10 02:20:50
in UTC. Then, the standard notation for this date will be 2021-06-10T02:20:50+00:00
.
On other hand, the JavaScript language provides a Date
object that represents a single moment in time. You can create a Date object in different ways:
let date;
date = new Date(); // Get the current date
date = new Date("2021-06-10T02:20:50+00:00"); // An object representation of given string date
date = new Date(new Date()); // Creates an object representation from another one
Also, we can set a time zone value to any given Date
object as follows:
let stringInput = "2021-06-10T02:20:50+00:00";
let timeZone = "America/Los_Angeles";
const dateObject = new Date(stringInput).toLocaleString("en-US", {
timeZone,
});
console.log(dateObject); // Prints: 6/9/2021, 7:20:50 PM
The toLocaleString
method returns a string with a language-sensitive representation of the Date
object. At the same time, this method supports optional arguments where you can configure the time zone. Find more information about this method here.
As you can see, the output date matches the configured time zone (GMT-7). However, we have a string representation of the date, and it would be much better if we work with a JavaScript object instead.
Luxon
Luxon is considered an evolution of Moment.js- a very popular library for date handling in the JavaScript ecosystem.
As the Luxon project says:
Luxon is a powerful, modern, and friendly wrapper for JavaScript dates and times.
Indeed, this library solves most of the common problems related to Date handling:
- Date internationalization
- Time zones and Offsets
- Calendars support
- Dates Formatting
- Dates Parsing
- Dates Math (Add/Subtract days, months, etc)
- Dates Validation
- and More...
The DateTime Object
The most important part of the Luxon library is the DateTime
object. It can be considered a wrapper of the native Date
object along with a timezone, and a local configuration.
The simplest way of creating a DateTime
object is as follows.
import { DateTime } from "luxon";
let dateTime = DateTime.local();
console.log("Current Date", dateTime.toISO()); // 2021-06-22T21:11:45.638-04:00
The method toISO()
will return an ISO 8601-compliant string representation of the DateTime
object.
Also, you can create a DateTime
in a specific time zone.
// Create a DateTime in a Specific Timezone
let zone = "America/Denver";
let dateTime = DateTime.fromObject({
zone,
});
console.log("Current Date", dateTime.toISO()); // 2021-06-22T19:11:45.640-06:00
As you can compare with the previous example, the time output is different because of the use of America/Denver
as the time zone.
Of course, there is a way to create a custom date in a specific time zone:
let dateTime = DateTime.fromObject({
'America/Denver',
}).set({
day: 1,
month: 5,
year: 2021,
});
console.log("Custom date", dateTime.toISO()); //2021-05-01T19:11:45.641-06:00
The set
method allows overriding specific properties such as year
, month
, day
, etc.
Converting a DateTime to a different Time Zone
Now let's suppose we have a DateTime
object, and we need to convert it to a different time zone.
let dateTime = DateTime.fromObject({
'America/Denver',
}).set({
day: 1,
month: 5,
year: 2021,
});
// Convert existing date to another Timezone
dateTime = dateTime.setZone("America/La_Paz");
console.log("Custom date, America/La_Paz", dateTime.toISO()); //2021-05-01T21:11:45.641-04:00
Configuring the Default Time Zone
What happens when the whole application needs to run every date in a specific time zone? Just suppose you have defined a configuration within your app to allow the selection of a time zone at any time.
To solve this problem, you don't need to use the time zone string here and there. The Settings
class, instead, comes to the rescue:
import { Settings } from "luxon";
// Configure the time zone
Settings.defaultZoneName = "America/Denver";
console.log(Settings.defaultZoneName); // Reading the configured time zone.
The defaultZoneName
can be used as a set
or get
method for the default time zone when you're working with the library.
In the same way, the Settings
class contains other methods to configure Luxon's behavior.
Then, when you're creating a new DateTime
object again, it will take the configured time zone by default.
dateTime = DateTime.local();
console.log("Configured defaultZoneName", dateTime.toISO()); //2021-06-22T19:21:54.362-06:00
Pay attention to the offset value, which corresponds now with America/Denver
.
Validate a Time Zone
In case you define a user entry point to configure the time zone globally, it is important to validate the text before causing problems with the DateTime
objects.
A useful way to do it is through, again, a DateTime
object:
const timeZone = "America/Not_Defined_TZ";
const myDateTime = DateTime.local().setZone(timeZone);
console.log("timeZone valid", myDateTime.isValid); // Prints 'false'
Now try again with a valid time zone, for example, America/Los_Angeles
.
Live Demo
Wanna play around with this code? Just open the embedded CodeSandbox editor:
Conclusion
In this article, I described a couple of useful methods for using Luxon for Time Zone handling using either JavaScript or TypeScript. Personally, I consider it a very useful library, and it also avoids rewriting and testing your own code for handling dates and time zones, which could save you a lot of time.
Feel free to reach out on Twitter if you have any questions. Follow me on GitHub to see more about my work.