2

I am finding a very strange behavior for different timezones in Python. The following code:

import datetime as dtm
import pytz


def test_tz():
    america_ny_tz: dtm.tzinfo = pytz.timezone("America/New_York")
    est_tz: dtm.tzinfo = pytz.timezone("EST5EDT")

    today = dtm.date.today()

    ny_dtm = dtm.datetime(
        year=today.year, month=today.month, day=today.day, tzinfo=america_ny_tz
    )
    est_dtm = dtm.datetime(
        year=today.year, month=today.month, day=today.day, tzinfo=est_tz
    )

    print(f"New York: {ny_dtm.timestamp()}, EST: {est_dtm.timestamp()}")


if __name__ == "__main__":
    test_tz()

outputs:

New York: 1609995360.0, EST: 1609995600.0

As you may notice the difference is about 4 minutes where one would have to assume the time should be the same.

Am I accessing time zone information incorrectly or is my understanding that the Time Zone information should be the same?

Running on Linux, Ubuntu 20.04 but the behavior on 18.04 was the same.

P.S. I haven't tried other languages or different OSs to see if the behavior will be the same.

martineau
  • 119,623
  • 25
  • 170
  • 301
Karlson
  • 2,958
  • 1
  • 21
  • 48
  • Concerning your p.s., the issue you encountered is library-specific, not OS-specific. same trouble on Windows ;-) And by the way, notice [this comment](https://github.com/eggert/tz/blob/846c3ac7abc246094dd754ac6dc90423148a5107/northamerica#L188) from Mr. Olson in the db - `EST5EDT` is obsolete. – FObersteiner Jan 07 '21 at 15:44
  • @MrFuppes I know that `EST5EDT` is obsolete but it is still in use, hence my issue. – Karlson Jan 07 '21 at 18:15

2 Answers2

2

This seems to be because one timezone uses Local Mean Time and the other is an offset of UTC (Universal Coordinated Time).

>>> pytz.timezone("America/New_York")
<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>
>>> pytz.timezone("EST5EDT")
<DstTzInfo 'EST5EDT' EST-1 day, 19:00:00 STD>
>>> pytz.timezone("LMT")

From https://www.timeanddate.com/time/local-mean-time.html

Local Mean Time was officially used as civil time in many countries during the 19th century. Each city had a different local time defined by its longitude, the difference amounting to 4 minutes per degree longtitude. This equals a distance of 50 miles or 81 kilometers on New York's latitude.

aviso
  • 2,371
  • 1
  • 14
  • 15
  • 2
    if you don't call localize, pytz falls back to using the first entry for the timezone in its database - which happens to be LMT. – FObersteiner Jan 07 '21 at 15:41
  • @MrFuppes and is supposed to have stopped in [late 19th century](https://github.com/eggert/tz/blob/846c3ac7abc246094dd754ac6dc90423148a5107/northamerica#L357) – Karlson Jan 07 '21 at 18:19
2

You need to localize correctly - with pytz's timezone objects, setting tzinfo directly when creating the datetime object is not the right way. It's in the docs:

This library only supports two ways of building a localized time. The first is to use the localize() method provided by the pytz library.

and

The second way of building a localized time is by converting an existing localized time using the standard astimezone() method


On the other hand, if you happen to use Python 3.9+, you can use the zoneinfo module from the standard lib to make you life easier - see the docs / using-zoneinfo or example usage here.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72