Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

what's the best way to use mktime() with time zones?

386 views
Skip to first unread message

Ed Morton

unread,
Aug 29, 2015, 5:55:54 PM8/29/15
to
Let's say I have an input file containing YYYY MM DD HH MM SS TZ values like:

$ cat file
2015 01 02 03 04 05 CST
2015 01 02 03 04 05 EDT
2015 01 02 03 04 05 GMT

I don't see an option to tell mktime() the timezone so when I run an awk script
I have to drop the timezone but then I get all "seconds since the epoch" as the
same value:

$ awk '{print mktime($1" "$2" "$3" "$4" "$5" "$6)}' file
1420189445
1420189445
1420189445

Do I need to create a manual mapping of timezone values to their delta in
seconds from my local time zone and then do math on the mktime return value to
get the real seconds since the epoch or is there a better way?

Ed.

Kenny McCormack

unread,
Aug 29, 2015, 9:47:16 PM8/29/15
to
In article <mrt9lt$r4q$1...@dont-email.me>,
I'm pretty sure that you do - i.e., there aren't any OS-provided shortcuts.

Keep in mind that timezone identifiers (such as shown above in your sample
file) are not globally unique. Both Sydney (Australia) and New York (USA)
are in EST (and EDT).

--
"They shall be attended by boys graced with eternal youth, who to the
beholder?s eyes will seem like sprinkled pearls. When you gaze upon that
scene, you will behold a kingdom blissful and glorious."

--- Qur'an 76:19 ---

Michal Jaegermann

unread,
Aug 30, 2015, 9:42:20 AM8/30/15
to
On Sat, 29 Aug 2015 16:55:47 -0500, Ed Morton wrote:

> Let's say I have an input file containing YYYY MM DD HH MM SS TZ values
> like:
>
> $ cat file
> 2015 01 02 03 04 05 CST
> 2015 01 02 03 04 05 EDT
> 2015 01 02 03 04 05 GMT
>
> I don't see an option to tell mktime() the timezone so when I run an awk
> script I have to drop the timezone

Not really. According to 'info gawk' the last field will be treated as
an "an optional daylight-savings flag" so awk will interpret that as 0 so
it will "vanish" by itself. To use that information it is likely the
easiest to tabulate required offsets in seconds and add those values to
whatever is returned by mktime(). Does not sound too complicated.

Michal

Bernd Nawothnig

unread,
Aug 30, 2015, 10:15:12 AM8/30/15
to
On 2015-08-30, Kenny McCormack wrote:
> Keep in mind that timezone identifiers (such as shown above in your sample
> file) are not globally unique. Both Sydney (Australia) and New York (USA)
> are in EST (and EDT).

Not according to this:

http://www.timeanddate.com/time/zones/
http://wiki.guildwars.com/wiki/Template:Timezone

The entries for Australia are:

AWST: Australian Western Standard Time (UTC+8)
ACST: Australian Central Standard Time (UTC+9:30)
ACDT: Australian Central Daylight Time (UTC+10:30)
AEST: Australian Eastern Standard Time (UTC+10)
AEDT: Australian Eastern Daylight Time (UTC+11)

So a simple dictionary timezone_shortcut -> seconds should be
sufficient.




Bernd

--
no time toulouse

Ed Morton

unread,
Aug 30, 2015, 10:31:02 AM8/30/15
to
Thanks to all who replied. Looks like I would need to write a mapping table for
the TZ values I expect to find in the input file but it's impossible to do in
general since some TZ values are not unique, e.g. from
http://www.timeanddate.com/time/zones/:

CST = Central Standard Time North America UTC -6:00
CST = China Standard Time Asia UTC +8:00
CST = Cuba Standard Time Caribbean UTC -5:00

Regards,

Ed.

Bernd Nawothnig

unread,
Aug 30, 2015, 12:06:33 PM8/30/15
to
On 2015-08-30, Ed Morton wrote:
> Thanks to all who replied. Looks like I would need to write a mapping
> table for the TZ values I expect to find in the input file but it's
> impossible to do in general since some TZ values are not unique, e.g.
> from http://www.timeanddate.com/time/zones/:
>
> CST = Central Standard Time North America UTC -6:00
> CST = China Standard Time Asia UTC +8:00
> CST = Cuba Standard Time Caribbean UTC -5:00

Arghl, that is ugly. Same for ACT, ADT, AMST, BST, and CDT:

ACT - Acre Time South America
ACT - Australien Central Time Australia

ADT - Arabia Daylight Time Asia
ADT - Atlantic Daylight Time North America
Atlantic

AMST - Amazon Summer Time South America
AMST - Armenia Summer Time Asia

BST - Bangladesh Standard Time Asia
BST - Bougainville Standard Time Pacific
BST - British Summer Time Europe

CDT – Central Daylight Time North America
CDT - Cuba Daylight Time Caribean

to be continued ...

Kenny McCormack

unread,
Aug 30, 2015, 4:15:44 PM8/30/15
to
In article <cofbbc-...@bernd.nawothnig.dialin.t-online.de>,
Bernd Nawothnig <Bernd.N...@web.de> wrote:
>On 2015-08-30, Kenny McCormack wrote:
>> Keep in mind that timezone identifiers (such as shown above in your sample
>> file) are not globally unique. Both Sydney (Australia) and New York (USA)
>> are in EST (and EDT).
>
>Not according to this:
>
>http://www.timeanddate.com/time/zones/
>http://wiki.guildwars.com/wiki/Template:Timezone
>
>The entries for Australia are:
>
>AWST: Australian Western Standard Time (UTC+8)
>ACST: Australian Central Standard Time (UTC+9:30)
>ACDT: Australian Central Daylight Time (UTC+10:30)
>AEST: Australian Eastern Standard Time (UTC+10)
>AEDT: Australian Eastern Daylight Time (UTC+11)

Even though it seems like this example is no longer valid (it was when I
visited Oz, though, granted, that was quite a few years ago), subsequent
posts on this thread have given other currently valid examples, so my
overall point is still valid. In fact, you yourself have posted many
examples of currently existing conflicts.

The bottom line is that a simple three (or four) letter code is not enough
information to identify a globally identify a timezone. It'd be better if
Ed's file could be re-created with a better timezone identification field.

--
Is God willing to prevent evil, but not able? Then he is not omnipotent.
Is he able, but not willing? Then he is malevolent.
Is he both able and willing? Then whence cometh evil?
Is he neither able nor willing? Then why call him God?
~ Epicurus

Andrew Schorr

unread,
Aug 30, 2015, 4:45:31 PM8/30/15
to
On Saturday, August 29, 2015 at 5:55:54 PM UTC-4, Ed Morton wrote:
> Do I need to create a manual mapping of timezone values to their delta in
> seconds from my local time zone and then do math on the mktime return value to
> get the real seconds since the epoch or is there a better way?

There is a better way if you are willing to download the gawk master branch. That has a new feature whereby changes to the ENVIRON array are reflected into the real environment. So this works:

bash-4.2$ echo "US/Eastern,2015 01 02 03 04 05
GMT,2015 01 02 03 04 05" | gawk -F, '{ENVIRON["TZ"] = $1; print mktime($2)}'
1420185845
1420167845

But this new feature is not in version 4.1.3. Using 4.1.3 or earlier, I'd launch a subshell to accomplish this rather than trying to implement timezones by yourself.

Regards,
Andy

Martin Neitzel

unread,
Aug 30, 2015, 7:42:14 PM8/30/15
to
> I would need to write a mapping table for the TZ values

Yes. Or this may help you:

GNU date(1) happens to be quite good at flexible date parsing. (This is
non-POSIX, and BSD systems vary wildly in their date(1) offers in this
respect.) GNU date(1) understands timezones names, and warns about the
"EST vs. EST" problem in its man page.

So, with your data and "in awk":

awk '
{
# system(sprintf(....)) or if you need the date as variable:
sprintf( "date -u +%%s -d \"%04d-%02d-%02d %02d:%02d:%02d %s\"",
$1, $2, $3, $4, $5, $6, $7) | getline epoche
print epoche # or whatever...
}' << !
2015 01 02 03 04 05 CST
2015 01 02 03 04 05 EDT
2015 01 02 03 04 05 GMT
!


Though I must admit that I had MUCH fun today doing it at first
without awk, learning a lot about quoting in xargs(1):

xargs -L 1 printf '"%04d-%02d-%02d %02d:%02d:%02d %s"\n' <<- ! |
2015 01 02 03 04 05 CST
2015 01 02 03 04 05 EDT
2015 01 02 03 04 05 GMT
!
xargs -L 1 date -u +"%s %c" -d

(In the end, a "while read line ..." loop would have been so much
simpler :-)

Martin

Ed Morton

unread,
Aug 30, 2015, 10:14:32 PM8/30/15
to
Good to know that's on it's way, thanks.

Ed.

Bernd Nawothnig

unread,
Aug 31, 2015, 6:03:14 AM8/31/15
to
On 2015-08-30, Kenny McCormack wrote:
>>The entries for Australia are:
>>
>>AWST: Australian Western Standard Time (UTC+8)
>>ACST: Australian Central Standard Time (UTC+9:30)
>>ACDT: Australian Central Daylight Time (UTC+10:30)
>>AEST: Australian Eastern Standard Time (UTC+10)
>>AEDT: Australian Eastern Daylight Time (UTC+11)
>
> Even though it seems like this example is no longer valid (it was when I
> visited Oz, though, granted, that was quite a few years ago), subsequent
> posts on this thread have given other currently valid examples, so my
> overall point is still valid. In fact, you yourself have posted many
> examples of currently existing conflicts.

Yes, my first assumption was wrong. Sorrowly it isn't that easy.
0 new messages