houseabsolute / DateTime-TimeZone

Time zone object base class and factory
https://metacpan.org/release/DateTime-TimeZone/
Other
9 stars 25 forks source link

Etc/GMT+4 is wrong (as are all Etc/GMT+/-) #47

Closed wolfsage closed 3 years ago

wolfsage commented 3 years ago

The Etc/GMT time_zones are backwards in newer DateTimes.

Here's an older DateTime (1.12) / DateTime::TimeZone (2.36), which is correct:

perl -MDateTime -e 'print "Now:   " . DateTime->now . "\nGMT+4: " . DateTime->now(time_zone=> "Etc/GMT+4") . "\n"'
Now:   2020-12-15T14:14:03
GMT+4: 2020-12-15T10:14:03

Here's a newer DateTIme (1.50) / DateTime::TimeZone (2.44), which has it backwards:

perl -MDateTime -e 'print "Now:   " . DateTime->now . "\nGMT+4: " . DateTime->now(time_zone=> "Etc/GMT+4") . "\n"'
Now:   2020-12-15T14:15:45
GMT+4: 2020-12-15T18:15:45

From https://data.iana.org/time-zones/tzdb/etcetera:

# Be consistent with POSIX TZ settings in the Zone names,
# even though this is the opposite of what many people expect.
# POSIX has positive signs west of Greenwich, but many people expect
# positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
# the abbreviation "-04" and corresponds to 4 hours behind UT
# (i.e. west of Greenwich) even though many people would expect it to
# mean 4 hours ahead of UT (i.e. east of Greenwich).

# Earlier incarnations of this package were not POSIX-compliant,
# and had lines such as
#       Zone    GMT-12      -12 -   GMT-1200
# We did not want things to change quietly if someone accustomed to the old
# way does a
#       zic -l GMT-12
# so we moved the names into the Etc subdirectory.
autarch commented 3 years ago

I moved this to the DateTime-TimeZone repo, since that's where the code to handle these zones lives.

autarch commented 3 years ago

I'm not sure how this worked for you with an older DT::TZ. Here's what I get with DateTime 1.12 and DateTime::TimeZone 2.36:

> perl -MDateTime -e 'print "Now:   " . DateTime->now . "\nGMT+4: " . DateTime->now(time_zone=> "Etc/GMT+4") . "\n"'
The timezone 'Etc/GMT+4' could not be loaded, or is an invalid name.
wolfsage commented 3 years ago

DateTime::TimeZone finds the following file:

# This file is auto-generated by the Perl DateTime Suite time zone
# code generator (0.08) This code generator comes with the
# DateTime::TimeZone module distribution in the tools/ directory

#
# Generated from /tmp/ZbFw0zNOVB/etcetera.  Olson data version 2019b
#
# Do not edit this file directly.
#
package DateTime::TimeZone::Etc::GMT_Plus4;

use strict;
use warnings;
use namespace::autoclean;

our $VERSION = '2.36';

use Class::Singleton 1.03;
use DateTime::TimeZone;
use DateTime::TimeZone::OlsonDB;

@DateTime::TimeZone::Etc::GMT_Plus4::ISA = ( 'Class::Singleton', 'DateTime::TimeZone' );

my $spans =
[
    [
DateTime::TimeZone::NEG_INFINITY, #    utc_start
DateTime::TimeZone::INFINITY, #      utc_end
DateTime::TimeZone::NEG_INFINITY, #  local_start
DateTime::TimeZone::INFINITY, #    local_end
-14400,
0,
'-04',
    ],
];

sub olson_version {'2019b'}

sub has_dst_changes {0}

sub _max_year {2029}

sub _new_instance {
    return shift->_init( @_, spans => $spans );
}

1;
wolfsage commented 3 years ago

Looks like we manually build our DateTime::TimeZone files with tools/parse_olson using --old

autarch commented 3 years ago

Looks like we manually build our DateTime::TimeZone files with tools/parse_olson using --old

That explains it.

autarch commented 3 years ago

Fixed in v2.45.