2

My web app client receive JSON data from rest api server.

Data contains timezone string value like as "Etc/GMT-1". For the time calculating, I need to extract timezone number (just like -1). If I use parseInt(timezone);, return value is NaN.

I am not sure if moment.js can handle this format and extract GMT number. I think timezone data format maybe flexible. So, I prefer to use moment.js.

Is there any way to extract number using moment.js?

Pa Rim
  • 61
  • 1
  • 1
  • 8

4 Answers4

4

The string "Etc/GMT-1" is a valid IANA time zone identifier. You can find it in the tzdb sources, and in the list on Wikipedia. As pointed out in the tzdb commentary, the sign is opposite from what you might expect. It means UTC+1, not UTC-1.

You also said: "I think timezone data format may be flexible." Indeed, if your data contains any tzdb zone identifiers, you should assume that all time zone identifiers are also valid, including the more conventional form like "America/Los_Angeles" or "Asia/Shanghai". Therefore, you should not try to extract anything from the string itself.

It's important to remember that while some zones have a single fixed offset, most represent a series of offsets and the transition points between them. Therefore, you should not try to get a single offset from a time zone id without also considering a point in time. This is also covered in the timezone tag wiki, under the topic "Time Zone != Offset".

To use these with moment.js, you will also need the moment-timezone add-on. For example:

var timeZone = 'Etc/GMT-1';  // your time zone

var m = moment.tz(timeZone);  // get the *current* time in the time zone.
// or
var m = moment.tz(input, timeZone); // get a *specific* time in the time zone.
// or
var m = someOtherMomentObject.clone().tz(timeZone); // convert to the time zone.

var n = m.utcOffset();  // 60  (minutes West of GMT at the given point in time)

var s = m.format('Z');  // "+01:00"  (offset as a string in ISO-8601 format)
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
0

If you also install moment-timezone, you can get the zone's offset:

var offsetHours = moment.tz.zone("Etc/GMT-1").offsets[0] / 60

The value of offsetHours variable will be -1. Note that I had to divide by 60, because the API returns the value in minutes.


As Matt reminded in the comments, usually timezones have more than one valid offset, depending on the date - due to Daylight Saving Time changes or even politicians deciding to change their country's offset - so it's better to get the offset based on a specific instant, as explained in the documentation:

moment.tz.zone('Etc/GMT-1').offset(1403465838805);

The parameter 1403465838805 is the number of milliseconds since 1970-01-01T00:00Z.

Specifically for Etc/GMT timezones, there's no difference since they have no offset variations, but for other zones, it's better to use an instant.

  • 2
    Careful with this approach. For the `Etc/GMT*` zones you're fine taking the first offset. But for other zones, the first entry is likely to be an LMT value. Better to ask for the offset at a particular point in time, than to evaluate the offsets array. – Matt Johnson-Pint Jul 15 '17 at 18:21
  • @MattJohnson Indeed! I've added this info to the answer, thanks a lot! –  Jul 15 '17 at 18:43
0

Etc/GMT-1 is a standard format. Apple has documentation for it: Documentation

Just FYI, As this Stackoverflow answear stated the Etc/GMT-1 should translate to GMT+1. If your input is always gonna be Etc/GMT# you can just extract it by writing you own one-line function as such:

function extract(input_string){
    return input_string.substring(input_string.indexOf("Etc/GMT")+7);
}
Hanzhao Deng
  • 118
  • 6
  • Apple has a *copy* of it. The better copy to link to is [the one on GitHub held by Paul Eggert](https://github.com/eggert/tz) (the current tzdb maintainer).The official tzdb release is [here](https://www.iana.org/time-zones). Also, I strongly discourage extracting a value from the string, for the reasons I pointed out in my answer. – Matt Johnson-Pint Jul 15 '17 at 18:24
0

Had the same problem so created an array with [ label, value ] for autocomplete. Enjoy.

// npm install -S moment-timezone

import moment from 'moment-timezone'
import timezones from '<path-to-node_modules>/node_modules/moment-timezone/data/unpacked/latest.json'

// Build Timezone Array for autocomplete
const TIMEZONES = timezones.zones.map( i => {
  let abbrs = i.abbrs.filter((el, index) => i.abbrs.indexOf(el) === index)
  return { label : `${i.name.replace('_',' ')} ( ${abbrs} )`, value: i.name}
})

Autocomplete Data Array

Michael Guild
  • 808
  • 9
  • 8