Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect the ID of the current user timezone using moment.js

Tags:

What I'm looking for is a way to detect the browser's timezone ID (as defined in the Olson tables) but I don't care for the exact ID, I just need the ID of a timezone that works the same as the user's one (for example "Europe/Rome" is fine if the user is in Paris).

I'm not interested in the current offset, I really need the timezone so that I can send it to the server to do computations for other dates (the server has the Olson tables too).

Theoretically, as I already use Moment.js timezone library and have included the Olson tables, I don't need anything else, but I don't find any API to do the detection. I don't know if it's hidden somewhere or if somebody has it already written. One of the problems is that the current timezone plugin seems to keep its data private.

I dont' want a solution based on the integration of yet another copy or extract of the Olson tables (which I would have to maintain), I know there are a few libraries duplicating them, I want to use the ones I already have in Moment.js.

like image 707
Denys Séguret Avatar asked Oct 17 '13 07:10

Denys Séguret


People also ask

How do you find the current time zone using a moment?

var tz = moment. tz. guess(); It will return an IANA time zone identifier, such as America/Los_Angeles for the US Pacific time zone.

Does moment use timezone?

The main moment. js library has full functionality for working with UTC and the local time zone. var testDateUtc = moment. utc("2015-01-30 10:00:00"); var localDate = moment(testDateUtc).

How can I get the timezone name in JavaScript?

In javascript , the Date. getTimezoneOffset() method returns the time-zone offset from UTC, in minutes, for the current locale.

How do you get time zone abbreviation in moment?

For example, if you parse the string '2020/01/02' and then call the moment#tz() method, you're telling moment to parse the string in the locale time, and then convert the date to a given IANA timezone. // '20200101 21:00 PST' moment('2020/01/02', 'YYYY/MM/DD'). tz('America/Los_Angeles'). format('YYYYMMDD HH:mm z');


1 Answers

I made a small script to do that detection. It starts by registering the ids of the available timezones, then, on a call to the matches function tests all timezone ids for the current time and the times 4 and 8 months later (to filter out the timezones with different daylight rules) and five years before.

Here it is :

<script src="moment-with-langs.min.js"></script>
<script src="moment-timezone.min.js"></script>
<script src="moment-timezone-data.js"></script>
<script>
var tzdetect = {
    names: moment.tz.names(),
    matches: function(base){
        var results = [], now = Date.now(), makekey = function(id){
            return [0, 4, 8, -5*12, 4-5*12, 8-5*12, 4-2*12, 8-2*12].map(function(months){
                var m = moment(now + months*30*24*60*60*1000);
                if (id) m.tz(id);
                return m.format("DDHHmm");
            }).join(' ');
        }, lockey = makekey(base);
        tzdetect.names.forEach(function(id){
            if (makekey(id)===lockey) results.push(id);
        });
        return results;
    }
};
</script>

If you just want one timezone id, simply use

var tzid = tzdetect.matches()[0];

Demonstration

GitHub Repository : https://github.com/Canop/tzdetect.js

Update : The code here shown isn't compatible with the most recent versions of moment.js. Please refer to the GitHub repository for a maintained (free to use) code.

2017 Update: There's now an API in moment.js to guess the timezone. That's probably the best solution right now.

like image 179
Denys Séguret Avatar answered Sep 17 '22 16:09

Denys Séguret