Getting the Client's Time Zone (And Offset) in Javascript

How can I gather the visitor's time zone information?

I need both:

  1. the time zone (for example, Europe/London)
  2. and the offset from UTC or GMT (for example, UTC+01)
8

32 Answers

Using an offset to calculate Timezone is a wrong approach, and you will always encounter problems. Time zones and daylight saving rules may change on several occasions during a year, and It's difficult to keep up with changes.

To get the system's IANA timezone in JavaScript, you should use

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

As of April 2022, this works in 93.5% of the browsers used globally.

Old compatibility information

ecma-402/1.0 says that timeZone may be undefined if not provided to constructor. However, future draft (3.0) fixed that issue by changing to system default timezone.

In this version of the ECMAScript Internationalization API, the timeZone property will remain undefined if no timeZone property was provided in the options object provided to the Intl.DateTimeFormat constructor. However, applications should not rely on this, as future versions may return a String value identifying the host environment’s current time zone instead.

in ecma-402/3.0 which is still in a draft it changed to

In this version of the ECMAScript 2015 Internationalization API, the timeZone property will be the name of the default time zone if no timeZone property was provided in the options object provided to the Intl.DateTimeFormat constructor. The previous version left the timeZone property undefined in this case.

12

Using getTimezoneOffset()

You can get the time zone offset in minutes like this:

var offset = new Date().getTimezoneOffset();
console.log(offset);
// if offset equals -60 then the time zone offset is UTC+01

The time-zone offset is the difference, in minutes, between UTC and local time. Note that this means that the offset is positive if the local timezone is behind UTC and negative if it is ahead. For example, if your time zone is UTC+10 (Australian Eastern Standard Time), -600 will be returned. Daylight savings time prevents this value from being a constant even for a given locale

Note that not all timezones are offset by whole hours: for example, Newfoundland is UTC minus 3h 30m (leaving Daylight Saving Time out of the equation).

Please also note that this only gives you the time zone offset (eg: UTC+01), it does not give you the time zone (eg: Europe/London).

12

Edit 3-19-2022 - WARNING: I no longer recommend this approach as it has issues with multiple browsers and locales.

I realize this answer is a bit off topic but I imagine many of us looking for an answer also wanted to format the time zone for display and perhaps get the zone abbreviation too. So here it goes...

If you want the client timezone nicely formatted you can rely on the JavaScript Date.toString method and do:

var split = new Date().toString().split(" ");
var timeZoneFormatted = split[split.length - 2] + " " + split[split.length - 1];

This will give you "GMT-0400 (EST)" for example, including the timezone minutes when applicable.

Alternatively, with regex you can extract any desired part:

For "GMT-0400 (EDT)" :

new Date().toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]

For "GMT-0400" :

new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]

For just "EDT" :

new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]

For just "-0400":

new Date().toString().match(/([-\+][0-9]+)\s/)[1]

Date.toString reference:

EDIT 10/6/2020 - The above solution may not work in all browsers and locales. If possible in your scenario, I would recommend utilizing a javascript library like date-fns, luxon or dayjs which provide timezone support.

12

It's already been answered how to get offset in minutes as an integer, but in case anyone wants the local GMT offset as a string e.g. "+1130":

function pad(number, length){
    var str = "" + number
    while (str.length < length) {
        str = '0'+str
    }
    return str
}

var offset = new Date().getTimezoneOffset()
offset = ((offset<0? '+':'-')+ // Note the reversed sign!
          pad(parseInt(Math.abs(offset/60)), 2)+
          pad(Math.abs(offset%60), 2))
5

You can use:

moment-timezone

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>

// retrieve timezone by name (i.e. "America/Chicago")
moment.tz.guess();

Browser time zone detection is rather tricky to get right, as there is little information provided by the browser.

Moment Timezone uses Date.getTimezoneOffset() and Date.toString() on a handful of moments around the current year to gather as much information about the browser environment as possible. It then compares that information with all the time zone data loaded and returns the closest match. In case of ties, the time zone with the city with largest population is returned.

console.log(moment.tz.guess()); // America/Chicago
2

I wrote a function in my project, which returns the timezone in hh:mm format. I hope this may help someone:

function getTimeZone() {
    var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
    return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}

// Outputs: +5:00
function getTimeZone() {
  var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
  return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}


// See output
document.write(getTimeZone());

Working Fiddle

3

A one-liner that gives both the offset and the time zone is to simply call toTimeString() on a new Date object. From MDN:

The toTimeString() method returns the time portion of a Date object in human readable form in American English.

The catch is that the timezone is not in the standard IANA format; it's somewhat more user-friendly, than the "continent/city" IANA format. Try it out:

console.log(new Date().toTimeString().slice(9));
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
console.log(new Date().getTimezoneOffset() / -60);

In California right now, toTimeString() returns Pacific Daylight Time while the Intl API returns America/Los_Angeles. In Colombia, you'd get Colombia Standard Time, vs. America/Bogota.

Note that many other answers to this question attempt to obtain the same information by calling Date.toString(). That approach is not that reliable, as MDN explains:

Date instances refer to a specific point in time. Calling toString() will return the date formatted in a human readable form in American English. [...] Sometimes it is desirable to obtain a string of the time portion; such a thing can be accomplished with the toTimeString() method.

The toTimeString() method is especially useful because compliant engines implementing ECMA-262 may differ in the string obtained from toString() for Date objects, as the format is implementation-dependent; simple string slicing approaches may not produce consistent results across multiple engines.

3

try getTimezoneOffset() of the Date object:

var curdate = new Date()
var offset = curdate.getTimezoneOffset()

This method returns time zone offset in minutes which is the difference between GMT and local time in minutes.

0

This question already has 30+ answers, but I am sure there are people who will come here and really don't know what they are looking for.

Surprise! you are about to open a can of worms!

I strongly recommend reading this article that I wrote recently about the headaches of dealing with TimeZones in JS!

What are you EXACTLY looking for?

Depending on your actually use case, you actually need different things.


James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.