1

I'm in the UK running these 2 commands (using gdate as I'm on a Mac with date (GNU coreutils) 8.32 installed):

# A UK winter date, timezone in UK at this time is GMT = UTC
$ gdate '--date=TZ="Australia/Sydney" 2021-02-11T03:02' +"%Y-%m-%d %T %z"
2021-02-10 16:02:00 +0000

# A UK summer date, timezone in the UK at this time is UTC+1
$ gdate '--date=TZ="Australia/Sydney" 2020-08-11T03:02' +"%Y-%m-%d %T %z"
2020-08-10 18:02:00 +0100

I expected %z to return the offset from UTC of the Sydney time, which would be something like +1200 or +1100. I'm only guessing at those, I was hoping gdate would tell me! But instead it's returning +0000 and +0100, which look suspiciously like my system's UTC offsets at those times.

man gdate has the following:

%z     +hhmm numeric time zone (e.g., -0400)

Which suggests that it should be doing what I expect, not what it's doing. Can anyone shed any light on this? Does GNU date use my system timezone for anything?


On @steeldriver's suggestion:

$ TZ=Australia/Sydney gdate '--date=2020-08-11T03:02' +"%Y-%m-%d %T %z"
2020-08-11 03:02:00 +1000

This (I think!) gives me what I wanted.

6
0

The date command is quite simple (on first look). But could become more complex once you look a bit deeper under its structure of values.

The simplest date command requires a "point in time" input and prints "a point in time" value (with additional changes guided by the format requested). If we rely on the default output format, we could do:

$ from='2020-08-11T03:02'

$ date -d "$from"

Tue 11 Aug 2020 03:02:00 AM EDT

That is assuming that the local set in the computer is in New_York. And that date would use the default TZ as set for both input and output.

Or, explicitly:

TZ="America/New_York" date -d "$from"
Tue 11 Aug 2020 03:02:00 AM EDT

That is the same date as the input from='2020-08-11T03:02' because date apply the set TZ to both input and output if there isn't additional information.

But the input string could be (also) written as:

from='2020-08-11T07:02 +0000' # Please note the 7 (instead of 3).

The same point in time as would be given by an user looking at time as it is in UTC.

$ TZ="America/New_York" date -d "$from"
Tue 11 Aug 2020 03:02:00 AM EDT

And the same command gives the same time value in New York as before, but the input value was different. It could have been to local time of someone in India:

$ from='2020-08-11T12:32+0530'

$ TZ="America/New_York" date -d "$from"

Tue 11 Aug 2020 03:02:00 AM EDT

Which results in the same value and "point in time" at New York.

To get the local string used above you do need the %z format:

from='2020-08-11T12:32+0530';TZ="Asia/Kolkata" date -d "$from"
Tue 11 Aug 2020 12:32:00 PM IST

from='2020-08-11T12:32+0530';TZ="Asia/Kolkata" date -d "$from" +'%c %z'
Tue 11 Aug 2020 12:32:00 PM IST +0530

Which is still the same "point in time" in New York:

from='2020-08-11T12:32+0530';TZ="America/New_York" date -d "$from" +'%c %z'
Tue 11 Aug 2020 03:02:00 AM EDT -0400

That is one use of the %z format.

The point is: a time string is not unique unless it also contains the value of the "time zone" used to generate such time string.

Olson database

I used numerical values above for the time zone: from='2020-08-11T12:32+0530'

But It is also possible (and recommendable) to use Olson database values:

from='TZ="Asia/Kolkata" 2020-08-11T12:32'; 

TZ="America/New_York" date -d "$from" +'%c %z'

Tue 11 Aug 2020 03:02:00 AM EDT -0400

The Olsen database values doesn't change with "summer time". It doesn't change from EST to EDT in "New York" at some (probably unknown to users from other countries) year date. It is stable.

TZ="America/New_York" date -d 'TZ="America/New_York" 01/01/20 03:30'
Wed 01 Jan 2020 03:30:00 AM EST

TZ="America/New_York" date -d 'TZ="America/New_York" 07/01/20 03:30'
Wed 01 Jul 2020 03:30:00 AM EDT

Using that concept, transformations of local time strings are possible (and easy) for cities either in the north or the south:

$ ddate(){ TZ="$toTZ" date -d 'TZ="'"$fromTZ"'" '"$1" +'%c %z'; }

$ toTZ='America/New_York'
$ fromTZ='Africa/Johannesburg'    # Which is in the south but has no DST.

$ ddate '1/1/20';ddate '4/1/20'; ddate '7/1/20'

Tue 31 Dec 2019 05:00:00 PM EST -0500
Tue 31 Mar 2020 06:00:00 PM EDT -0400
Tue 30 Jun 2020 06:00:00 PM EDT -0400 


$ fromTZ='Pacific/Auckland'                   # Which has a DST set.

$ ddate '1/1/20';ddate '4/1/20'; ddate '7/1/20'

Tue 31 Dec 2019 06:00:00 AM EST -0500
Tue 31 Mar 2020 07:00:00 AM EDT -0400
Tue 30 Jun 2020 08:00:00 AM EDT -0400

Note the three **different** times 6, 7 and 8.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.