in reply to Re^2: Question regarding Time::Piece and timezones
in thread Question regarding Time::Piece and timezones

I've been trying to implement the OP's application using your suggestions. I did get DateTime and DateTime::Format::Strptime installed.
However I seem to be doing something stupid as I can't get to square #1 - creating the $strp object (error shown below).

I would appreciate your help in correcting my error. I am also curious as to what happens with these ambiguous local times, like in the US 1:23 AM can occur twice during the same day. Almost all my work is in GMT/UTC so I don't often work with local time myself.

use strict; use warnings; use 5.010; use DateTime; use DateTime::Format::Strptime; $|=1; my $str = 'Wed, 13 Jan 2021 17:22:23'; my $pattern = '%a, %d %b %Y %T'; my $strp = DateTime::Format::Strptime->new( pattern => $pattern, time_zone => 'CST', zone_map => { CST => '-0700', EST => '-0600' } ); say "I got this far (not!)"; my $dt = $strp->parse_datetime( $str ); say "String: $str"; say "DateTime: $dt"; say ''; __END__ Invalid offset: CST
Update: BTW, there are all kind of "weirdo" time zones in the world time zones. Also occasionally a specific location can change its time zone - the International Date Line was moved some years back - this affected some islands in the Pacific.

Replies are listed 'Best First'.
Re^4: Question regarding Time::Piece and timezones
by haukex (Bishop) on Jan 22, 2021 at 14:51 UTC
    I am also curious as to what happens with these ambiguous local times, like in the US 1:23 AM can occur twice during the same day.

    What...? Anyway, see the %p and %P tokens.

    Invalid offset: CST

    As per DateTime::Format::Strptime: "By default, the parser will die when it parses an ambiguous abbreviation."

    $ perl -wMstrict -MDateTime -le 'print DateTime->now(time_zone=>$_)->s +trftime("%Z %z") for qw# America/Havana Asia/Shanghai America/Chicago + #' CST -0500 CST +0800 CST -0600

    See also List of time zone abbreviations, ISO8601 Time zone designators, and Names of time zones.

    Also occasionally a specific location can change its time zone - the International Date Line was moved some years back - this affected some islands in the Pacific.

    Hence the existence of location-based time zone names that are unambiguous in that respect.

    $ perl -wMstrict -MDateTime -le 'print DateTime->new(year=>$_,time_zon +e=>"Pacific/Apia")->strftime("%Y %z") for qw/ 2010 2012 /' 2010 -1100 2012 +1400
        Daylight Saving.

        Hm, yes, true if one reads the question without the context of the rest of the thread. My confusion stemsmed from the fact that the thread includes YMD and time zone names that would normally resolve that ambiguity. Update: Of course the time zone names used in the following are still ambiguous in other ways, as per my post above. Update 2&3: Upon rereading: the "in the US" bit is still confusing me, since this ambiguity is true of any time zone that observes DST, hence my assumption that this had something to do with AM/PM rather than DST. Other minor reformatting.

        use warnings; use strict; use DateTime::Format::Strptime; my $strp = DateTime::Format::Strptime->new( pattern => '%F %H:%M %P %Z', on_error => 'croak', zone_map => { CST => '-0600', CDT => '-0500' } ); for my $str ('2020-03-08 1:23 AM CST','2020-03-08 1:23 AM CDT') { print $str, " = "; my $dt = $strp->parse_datetime($str); $dt->set_time_zone('UTC'); print $dt->strftime('%F %T %Z'), " = "; $dt->set_time_zone('America/Chicago'); print $dt->strftime('%F %T %Z'), "\n"; } __END__ 2020-03-08 1:23 AM CST = 2020-03-08 07:23:00 UTC = 2020-03-08 01:23:00 + CST 2020-03-08 1:23 AM CDT = 2020-03-08 06:23:00 UTC = 2020-03-08 00:23:00 + CST
      I guess that what this nets out to, is that if you log a "local time", you also need the time_zone.

      I am in the US Pacific Time Zone (PST).
      Once per year, a "day" will have 25 hours.
      My wristwatch will wind up showing 1:15 AM twice during that day.
      It is Ok that 1:15 AM PST and 1:15 AM PDST converts to a different GMT time,
      but the time zone matters.

      I recommend converting all times to GMT/UTC within the DB.

Re^4: Question regarding Time::Piece and timezones
by Fletch (Chancellor) on Jan 21, 2021 at 06:39 UTC

    It's too late to be poking at things but I think the problem is that the argument validation is trying to coerce "CST" into a DateTime::TimeZone before it's done anything to do looking at your mapping. I think what that argument is for is providing a mapping for zones if they're named in the date which is being parsed. Tweaking your code slightly:

    #!/usr/bin/env perl use strict; use warnings; use 5.010; use DateTime; use DateTime::Format::Strptime; $|=1; my $str = 'Wed, 13 Jan 2021 17:22:23 CST'; my $pattern = '%a, %d %b %Y %T %Z'; my $strp = DateTime::Format::Strptime->new( pattern => $pattern, zone_map => { CST => '-0700', EST => '-0600' } ); say "I got this far (not!)"; my $dt = $strp->parse_datetime( $str ); say "String: $str"; say "DateTime: $dt"; say "zone: ", $dt->time_zone->name; say ''; __END__ $ perl tz_thing.plx I got this far (not!) String: Wed, 13 Jan 2021 17:22:23 CST DateTime: 2021-01-13T17:22:23 zone: -0700

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      I think what that argument is for is providing a mapping for zones if they're named in the date which is being parsed.

      Yes, I agree, time_zone makes sense when the string being parsed doesn't contain a time zone specification, and zone_map makes sense when it does contain a time zone specification.

      Your code works on my machine. Thanks!

      Evidently CST is ambiguous because there is a China Time Zone.
      zone_map{} appears to be necessary.