Tuesday, July 18, 2023

How to Work With Time Zones in JavaScript

How to Work With Time Zones in JavaScript

For a long time our civilization has used the relative position of sun in the sky to determine what time it is at a specific moment during the day. However, the position of sun in the sky varies for different locations on earth even at the same point of time. For example, what might be afternoon in India would be close to midnight in the United States.

I used an extreme example above but using the sun as a basis to decide what time it is can result in different cities having different time even if they are not much further apart. This can result in a variety of problems such as scheduling conflicts. Let's say you decide to video chat with your friend at 9:30 in the morning. However, their 9:30 will be different than yours. Time zones become important for long distance travel or communication.

One solution to this problem is the use of time zones. A time zone is any region of the Earth with the same standard time.

In this tutorial, we will learn a little bit about time zones and how to work with time zones in JavaScript.

Understanding the Basics of Time Zones

As I mentioned earlier, some parts of the Earth will experience noon while others have midnight. Therefore, it doesn't make sense for the entire Earth to operate on the same time.

The Earth has been divided into 24 time zones to solve this issue. All points that fall within the same time zone will have the same time.

We begin with the assumption of a Coordinated Universal Time or UTC which represents Greenwich Mean Time. UTC does not change due to daylight saving time or regional variations. This makes UTC a widely-used time standard for any tasks that require scheduling over continental distances.

A flight that leaves London at 5:00 UTC will mean the same thing in Sydney, Australia and Los Angeles, United States.

An offset is added to the UTC to indicate that we are moving hours ahead (+) or hours behind (-) as we cross longitudes. For example, Japan has Japan Standard Time which translates to UTC+9:00. Samoa has Samoa Standard Time which is UTC-11:00.

Not all countries and regions strictly follow the convention of longitudinal lines to divide themselves in time zones. For example, geographically large countries such as India and China still observe a single standard time. India could have multiple time zones but it follows Indian Standard Time which is UTC+5:30. Similarly, China follows China Standard Time which is UTC+8:00.

Whenever we talk about time, it is important to mention the time zone if we are communicating with places that are geographically far apart.

The Date Object and Time Zones in JavaScript

The Date object in JavaScript basically represents the number of milliseconds that have passed since the midnight at the beginning of January 1, 1970 UTC. This value is timezone-agnostic which basically means that it will stay the same across time zones.

These number of elapsed seconds are also called timestamp. The maximum and minimum value of timestamp is ±8,640,000,000,000,000. This covers dates ranging from April 20, 271821 BC to September 13, 275760 AD. That's a lot of time!

It is possible to get the timestamp value for a date by using the getTime() method. This method is time zone agnostic. Here are some examples:

1
let now_india = new Date();
2
3
// Outputs: Date Thu Jun 08 2023 09:43:04 GMT+0530 (India Standard Time)

4
console.log(now_india);
5
6
// Outputs:  1686197601087

7
console.log(now_india.getTime());
8

Now I'll change my system time zone to Wellington and call getTime() again.

1
let now_wellington = new Date();
2
3
// Outputs: Date Thu Jun 08 2023 16:13:21 GMT+1200 (New Zealand Standard Time)

4
console.log(now_wellington);
5
6
// Outputs: 1686197601087

7
console.log(now_wellington.getTime());

The getTime() values differ a little bit due to the delay in switching of time zones. However, you can see that the difference isn't as huge as it would be if getTime() actually relied on local system time.

Another important thing to note here is that logging the values of now_india and now_wellington to the console results in the output of date and time with their respective time zones.

Getting the Time Components in UTC

Since UTC is the reference against which the time in other zones is represented, you might want to get the value of different components of time in UTC every now and then.

Fortunately, there are a variety of methods to help you do that.

  1. getUTCFullYear() will give you the year for a particular date according to universal time.
  2. getUTCMonth() will give you the month for a particular date according to universal time.
  3. getUTCDate() will give you the day of the month for a particular date according to universal time.
  4. getUTCHours() will give you the hours for a particular date according to universal time.
  5. getUTCMinutes() will give you the minutes for a particular date according to universal time.
  6. getUTCSeconds() will give you the seconds for a particular date according to universal time.

The following code snippet shows how the output of these methods can differ from regular methods that return local values for specific dates.

1
let newyear_india = new Date('2024-01-01T01:20:30.000+05:30');
2
3
// Outputs: New Year in India: Tue Jan 01 2024 01:20:30 GMT+0530 (India Standard Time)

4
console.log(`New Year in India: ${newyear_india}`);
5
6
// Outputs: Year in India: 2024 | Year in UTC: 2023

7
console.log(`Year in India: ${newyear_india.getFullYear()} | Year in UTC: ${newyear_india.getUTCFullYear()}`);
8
9
// Outputs: Month in India: 0 | Month in UTC: 12

10
console.log(`Month in India: ${newyear_india.getMonth()} | Month in UTC: ${newyear_india.getUTCMonth()}`);
11
12
// Outputs: Date in India: 1 | Date in UTC: 31

13
console.log(`Date in India: ${newyear_india.getDate()} | Date in UTC: ${newyear_india.getUTCDate()}`);
14
15
// Outputs: Hours in India: 1 | Hours in UTC: 19

16
console.log(`Hours in India: ${newyear_india.getHours()} | Hours in UTC: ${newyear_india.getUTCHours()}`);
17
18
// Outputs: Minutes in India: 20 | Minutes in UTC: 50

19
console.log(`Minutes in India: ${newyear_india.getMinutes()} | Minutes in UTC: ${newyear_india.getUTCMinutes()}`);
20
21
// Outputs: Seconds in India: 30 | Seconds in UTC: 30

22
console.log(`Seconds in India: ${newyear_india.getSeconds()} | Seconds in UTC: ${newyear_india.getUTCSeconds()}`);

Output Date and Time for Different Locales and Time Zones

The Date object in JavaScript has a few useful methods that allow us to present any particular date using specific locales within the time zones we want.

Different countries write the months, years, and days for a date differently. You can use the toLocaleDateString() method in order to return a string that contains language-specific representation of the given date in the time zone of the user.

Here is an example:

1
let now = new Date('2024-12-31T00:00:00+00:30');
2
const options = { weekday: 'short', year: 'numeric', month: 'long', day: 'numeric' };
3
4
// Outputs: 31/12/2024

5
console.log(now.toLocaleDateString('en-IN'));
6
7
// Outputs: Tue, 31 December, 2024

8
console.log(now.toLocaleDateString('en-IN', options));
9
10
// Outputs: 12/31/2024

11
console.log(now.toLocaleDateString('en-US'));
12
13
// Outputs: Tue, December 31, 2024

14
console.log(now.toLocaleDateString('en-US', options));
15
16
// Outputs: Tue, 31 December 2024

17
console.log(now.toLocaleDateString('en-GB', options)); 

As you can see, a change in the locale had no effect on the time zone. Otherwise, the date would have been different for United States. The time zone stays whatever it is on the local machine which is IST in this case.

You can use the toLocaleString() method to get a string representation of all the components in the Date object. The method accepts two optional parameters. First one is the locales and can have values like en-US, en-AU, and de-DE etc. The second parameter is the options object which controls how the information is displayed to the user.

Here is an example of using this method:

1
let now = new Date();
2
3
let now_india = now.toLocaleString("en-IN", {
4
    dateStyle: "medium",
5
    timeStyle: "medium",
6
    timeZone: "Asia/Kolkata"
7
});
8
document.querySelector("p.india").innerText = now_india;
9
10
let now_sydney = now.toLocaleString("en-AU", {
11
    dateStyle: "medium",
12
    timeStyle: "medium",
13
    timeZone: "Australia/Sydney"
14
});
15
document.querySelector("p.aus").innerText = now_sydney;
16
17
let now_new_york = now.toLocaleString("en-US", {
18
    dateStyle: "medium",
19
    timeStyle: "medium",
20
    timeZone: "America/New_York"
21
});
22
document.querySelector("p.us").innerText = now_new_york;

We begin by storing a Date object in our variable now. This represents the current local date and time at the execution of the code. After that, we use the toLocaleString() method to get a representation of that date in our preferred locale and time zone. The returned string is ultimately used to set value of the innerText property for a bunch of p elements.

You can wrap the above code in a function called updateTime() and use the code below to create three clocks that show time from three major cities around the world.

1
updateTime();
2
setInterval(updateTime, 1000);

Here's a CodePen that I have put together to demonstrate this functionality:

Final Thoughts

Quite a few things that we do in our day-to-day lives depend on knowing the correct date and time either at our present location or somewhere else far away. This tutorial began with a brief introduction of the need and use of time zones. After that, we moved on to the actual task a hand, learning how to work with time zones in JavaScript.

A lot of built-in methods of the JavaScript Date object give results based on the local time. However, there are some UTC specific methods as well as methods like toLocaleString() that help you convert any date into a locale and time zone specific version.


No comments:

Post a Comment