3

As far as I know, United States Eastern Time is GMT-5 for Eastern Standard Time, and GMT-4 for Eastern Daylight Time.

So why do these two commands give different hours in the answers?

laptop % TZ=EST5EDT date
Wed Apr 27 12:16:36 EDT 2022
laptop % TZ=GMT-4 date
Wed Apr 27 20:16:40 GMT 2022

Shouldn't they be the same?

3
  • Yes, for some reason unbeknownst to me, zoneinfo calls GMT-4 what most people call GMT+4 and vice versa.
    – egmont
    Apr 27, 2022 at 16:21
  • Here in the UK, currently one hour ahead of UTC, date +%z returns me +0100 ("you are one hour ahead of UTC"). I would expect the same command to return you -0400 ("you are four hours behind UTC"). Does it do so? Apr 27, 2022 at 16:34
  • 1
    @roaima Yes, date +%z answers -0400
    – hymie
    Apr 27, 2022 at 16:35

1 Answer 1

11

There are actually two main ways to use the TZ variable. The older one is specified in the POSIX standards, and it can encode the timezone and the current year's Daylight Saving Time rules in the actual variable. For example, an European UTC+2 hours timezone might be fully specified like this POSIX-style:

TZ=EET-2EEST,M3.5.0/3,M10.5.0/4
  • EET = "standard time" timezone ID ("East European Time")
  • -2 = offset you must add to local time to get UTC
  • EEST = DST timezone ID ("East European Summer Time")
  • M3.5.0/3 = DST takes effect last Sunday of March, 03:00:00 local time
  • M10.5.0/4 = standard time resumes last Sunday of October, 04:00:00 local time

Note that this format assumes the DST rule for the current year also applies to any past and future years... an assumption that is unlikely to be correct.

Since this was clearly less than desirable, many unix-style OSs use the TZ environment variable instead as a reference to a more extended table of timezone information, covering both current and historical definitions for a particular timezone.

The most comprehensive of these table-based implementations is the Olson time zone information database, which is now maintained by IANA. An Olson-style TZ value is usually in <Continent>/<City> format, but the database has some other options too. You can use either form in the TZ variable, but if the value is ambiguous, the POSIX format takes precedence since it's the established standard.

The POSIX standard definition of the TZ variable is "backwards" of what you might naturally assume. The number after the first timezone label identifies the number of hours you must add to the local time in order to get the UTC time.

This is probably because before the POSIX standard was developed, different versions of the TZ environment variable convention already existed... and since Unix was originally developed in the Western Hemisphere, the existing conventions tended to use positive numbers for US timezones. (During the early days of Unix, nobody may have guessed that a mostly-academic offshoot of the MULTICS OS development project would grow into something bigger and long-lived.)

I've understood that the developers of the POSIX specifications tried to the best of their ability to find the behavior that was already the most common, and codified it as the standard, unless there was a very obvious reason to do otherwise.

So, TZ=GMT-4 gets interpreted in POSIX-style... and then it does not mean "a timezone that is GMT minus four hours": it actually means "a timezone that is four hours ahead of UTC and named GMT". You may call your custom timezones anything you want, I guess, but reusing a well-known historical timezone identifier for something entirely different is going to cause confusion.

If you want to specify a timezone by just "GMT" in Linux, then you should use the newer Olson style of TZ settings by adding the Etc/ prefix... and even then, the sign convention is reversed of what you would expect, probably to maintain the analogy to the older POSIX-style settings.

Compare:

$ TZ=Etc/GMT-4 date
Wed 27 Apr 21:09:32 +04 2022     # Olson: 4 hours east of UTC, timezone correctly identified numerically 
$ TZ=GMT-4 date
Wed 27 Apr 21:09:50 GMT 2022     # POSIX: 4 hours east of UTC, misleading timezone identifier!
$ TZ=Etc/GMT+4 date
Wed 27 Apr 13:09:39 -04 2022     # Olson: 4 hours west of UTC, timezone correctly identified numerically
$ TZ=GMT+4 date  
Wed 27 Apr 13:10:14 GMT 2022     # POSIX: 4 hours west of UTC, misleading timezone identifier!
$ date -u
Wed 27 Apr 17:10:25 UTC 2022     # UTC time for reference.
3
  • Wow, that makes an awful lot of sense. Thank you for comparing "GMT-4" to the one I'm used to, "EST5EDT" -- now I think I understand. (And yes, as you noted, I was seeing the same reversed-sign behavior with the files in Etc/ )
    – hymie
    Apr 27, 2022 at 18:38
  • The original maven of tzdb (and tzlist) was Arthur David Olson -- with two 'o' and no 'e'. Otherwise +1 (but only in one hemisphere and I'm not sure which :-) Apr 28, 2022 at 5:07
  • @dave_thompson_085 Oops, that's what I get from trusting my memory. Name corrected.
    – telcoM
    Apr 28, 2022 at 5:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .