sdispater / pendulum

Python datetimes made easy
https://pendulum.eustace.io
MIT License
6.18k stars 381 forks source link

Timezone inconsistency #363

Open cottongin opened 5 years ago

cottongin commented 5 years ago

Most/all properly formatted IANA timezones work fine, however there appear to be several shortcuts coded into pendulum, for example: EST, MST, CST (curiously not PST). The DST equivalents do not exist (EDT, MDT, CDT, PDT). Can these inconsistencies be clarified/fixed or shortcuts removed?

Further, all Etc/GMT timezones appear to return the opposite of what I would expect. Etc/GMT-6 returns +06, for example

ghost commented 5 years ago

Further, all Etc/GMT timezones appear to return the opposite of what I would expect. Etc/GMT-6 returns +06, for example

@cottongin I believe that reversal is expected -- The Etc zones conform to the POSIX style:

The special area of "Etc" is used for some administrative zones, particularly for "Etc/UTC" which represents Coordinated Universal Time. In order to conform with the POSIX style, those zone names beginning with "Etc/GMT" have their sign reversed from the standard ISO 8601 convention. In the "Etc" area, zones west of GMT have a positive sign and those east have a negative sign in their name (e.g "Etc/GMT-14" is 14 hours ahead of GMT.)

https://en.wikipedia.org/wiki/Tz_database#Area

zhangchunlin commented 5 years ago

Yes, I also found the problem:

def test40():
    from datetime import datetime
    import pendulum

    g8 = pendulum.timezone('Etc/GMT+8')
    print(g8)
    print(datetime(2011, 9, 13, 20, 14, 15,tzinfo=g8))

    sh = pendulum.timezone('Asia/Shanghai')
    print(sh)
    print(datetime(2011, 9, 13, 20, 14, 15,tzinfo=sh))

    g8m = pendulum.timezone('Etc/GMT-8')
    print(g8m)
    d = datetime(2011, 9, 13, 20, 14, 15, tzinfo=g8m)
    print(d)

if __name__ == '__main__':
    test40()

Output:

Timezone('Etc/GMT+8')
2011-09-13 20:14:15-08:00
Timezone('Asia/Shanghai')
2011-09-13 20:14:15+08:00
Timezone('Etc/GMT-8')
2011-09-13 20:14:15+08:00
jtrakk commented 5 years ago

I believe this is the correct behavior per POSIX standard.

zhangchunlin commented 5 years ago

@jtrakk Could you explain the detail? Because 'Asia/Shanghai' is in 'Etc/GMT+8', so the result should be the same, right?

jtrakk commented 5 years ago

@zhangchunlin All the Etc/GMT±X indicators use the opposite sign from UTC±X. Etc/GMT+8 is equivalent to UTC−08:00, Pacific Standard Time.

In [13]: pendulum.parse('2019-08-22T09:30:55+08:00').offset                                                                                                                                                                                                                                            
Out[13]: 28800

In [14]: pendulum.parse('2019-08-22T09:30:55+08:00').in_tz('Asia/Shanghai').offset                                                                                                                                                                                                                     
Out[14]: 28800

See also https://en.wikipedia.org/wiki/Tz_database#Area

zhangchunlin commented 5 years ago

@jtrakk Thank you for your information! the full list can be seen here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones In my application, I will filter to ignore these confusing timezone names.

harvidsen commented 1 month ago

I also have a problem related to this.

>>> pendulum.now(tz="Europe/Oslo").tzname()
'CEST'

This gives pytz.exceptions.UnknownTimeZoneError: 'CEST' in other applications that use pytz. I also see that CEST is not an actual TZ identifier in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones, but just an abbreviation of many others.

Please let me know if I should open a separate issue for this.