sdispater / pendulum

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

wrong hour in timezone "America/Mexico_City" #700

Open joaquin-casanova opened 1 year ago

joaquin-casanova commented 1 year ago

Issue

The library return a wrong hour for timezone America/Mexico_City by 1 hour in the future.

import pendulum

now = pendulum.now("America/Mexico_City") now

notatallshaw-gts commented 1 year ago

You probably have an old timezone database on your machine: https://www.mexperience.com/mexico-set-to-abandon-seasonal-clock-time-changes/

It looks like you need at least 2022f: http://mm.icann.org/pipermail/tz-announce/2022-October/000075.html

Likely updating tzdata to >= 2022.6 will fix this: https://github.com/python/tzdata/releases/tag/2022.6

jpradass commented 1 year ago

I'm having the same issue as Joaquin. With pendulum, pytz and tzdata updated to their latest versions, their giving me different results:

>>> pendulum.__version__
'2.1.2'
>>> pytz.__version__
'2023.3'
>>> tzdata.__version__
'2023.3'

>>> mexico = pendulum.timezone('America/Mexico_City')
>>> tz = pytz.timezone('America/Mexico_City')
>>> datetime.datetime.now(mexico)
datetime.datetime(2023, 4, 4, 6, 24, 45, 810564, tzinfo=Timezone('America/Mexico_City'))
>>> datetime.datetime.now(tz)
datetime.datetime(2023, 4, 4, 5, 24, 49, 840461, tzinfo=<DstTzInfo 'America/Mexico_City' CST-1 day, 18:00:00 STD>)

I double checked with the system timezone and it is fixed as it should be:

[root@521fd6d88911 /]# TZ='America/Mexico_City' date
Tue Apr  4 05:28:30 CST 2023

Check that Mexico_City is now on CST time frame.

notatallshaw-gts commented 1 year ago

I can reproduce this issue but interestingly I don't have tzdata installed, also if just run the following on the command line I get the wrong time:

TZ=America/Mexico_City date

So it seems Pendulum is falling about to the locally installed database? Where as pytz is not? Perhaps someone can figure out the logic of where it's sourcing it and if it can be changed?

vxtals commented 1 year ago

I'm having this issue too. I think this is happening because the last release of pendulum (2.1.2), is using the last version (from 2020) of pytzdata. The 3.0.0a prerelease of pendulum stops using pytzdata, at least for python > 3.9 and starts using built in zoneinfo. The problem is that this prerelease is not stable and has other breaking changes, so we can't use it.

I see three options:

vxtals commented 1 year ago

In order to make pytzdata stop using its bundle zoneinfo data you can set this env variable:

export PYTZDATA_TZDATADIR=/usr/share/zoneinfo

so it will use the system zoneinfo data.

joaquin-casanova commented 1 year ago

I have used this approach thanks to the advice of @vxtals import pendulum import pytzdata

pytzdata.set_directory("/usr/share/zoneinfo")

LOCAL_TZ_NAME = "America/Mexico_City" LOCAL_TZ = pendulum.timezone(LOCAL_TZ_NAME)

now = pendulum.now(LOCAL_TZ)

now

alex-astronomer commented 1 year ago

I believe that this problem is going to be very apparent for many users as Apache Airflow uses pendulum for time operations.

https://github.com/apache/airflow/issues/30605

NickFabry commented 1 year ago

This is caused by pendulum release 2.1.2 referencing (now) obsolete IANA zoneinfo, specifically 2022.1. As a temporary fix, to force pendulum 2.1.2 to use either the system zoneinfo, or (on Windows), the zoneinfo from the first party module tzdata, put the following into your python import path as (for example) pendulum_212_fix.py, and after you import pendulum, add the line import pendulum_212_fix, and you should be good.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module has one purpose - to fix the behavior of pendulum release
2.1.2, which uses a hardcoded version of the IANA zoneinfo data, 2022.2.
Importing this module after importing pendulum should cause pendulum to
use either the OS provided zoneinfo data, or if that does not exist, to
use the zoneinfo from the first party module tzdata. Note this introduces
a dependence on tzdata, which must be separetely installed, typically via
pip install tzdata.

In theory, IMMEDIATELY AFTER IMPORTING pendulum, you should simply
import this module and pendulum will then use the local system
zoneinfo, if available, and if not, the zoneinfo from tzdata, when
creating aware datetimes.
"""

import pathlib
import sysconfig
import tzdata

LOCAL_TZPATH = sysconfig.get_config_var('TZPATH')
if LOCAL_TZPATH:
    # This could be a colon separated list of paths; we take the first only
    LOCAL_TZPATH = LOCAL_TZPATH.split(':')[0]
else:
    LOCAL_TZPATH = pathlib.Path(tzdata.__path__) / 'zoneinfo'

import pendulum
import pytzdata
pytzdata.set_directory(LOCAL_TZPATH)

if __name__ == '__main__':
    pass
demxic commented 1 year ago

Is there any other way?

Seems to me, like there is something wrong here: LOCAL_TZPATH = pathlib.Path(tzdata.__path__) / 'zoneinfo'

I have been trying all solutions provided but still can´t make America/Mexico_City timezone work.

Any other insights?

joaquin-casanova commented 1 year ago

Well the other option is to use another time zone with the same time as Mexico_City such as America/Guatemala.

This is the last resource