sdispater / pendulum

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

Regression from Pendulum 1.4.4 to Pendulum 2.1.2: in_tz() can change the timestamp of a pendulum time #535

Open gibsondan opened 3 years ago

gibsondan commented 3 years ago

Issue

After updating from pendulum 1.4.4 to pendulum 2.1.2, I found that the in_tz() function now sometimes changes the timestamp of a pendulum time (specifically around DST transitions). I was under the impression that this method will change the timezone, but should never change the UTC timestamp of the underlying datetime.

Repro of the issue:

in pendulum 2.1.2:

>>> import pendulum
>>> the_time = pendulum.datetime(2019,11,3,0,tz="US/Central").add(hours=1)
>>> str(the_time)
'2019-11-03T01:00:00-05:00'
>>> str(the_time.in_tz("US/Central"))
'2019-11-03T01:00:00-06:00'

As you can see, calling in_tz has caused the time to jump forward an hour.

Similar code in pendulum 1.4.4 that does not have the problem (in_tz doesn't change the timestamp):

>>> import pendulum
>>> the_time = pendulum.create(2019,11,3,0,tz="US/Central").add(hours=1)
>>> str(the_time)
'2019-11-03T01:00:00-05:00'
>>> str(the_time.in_tz("US/Central"))
'2019-11-03T01:00:00-05:00'
Jari27 commented 1 year ago

I have a similar (the same?) issue. When converting a PRE_TRANSITION timezone to the same timezone, it will change to POST_TRANSITION. Version 2.1.2.

>>> time = pendulum.datetime(2023, 10, 29, 2, tz="Europe/Amsterdam", dst_rule=pendulum.PRE_TRANSITION)
>>> str(time)
'2023-10-29T02:00:00+02:00'
>>> str(time.in_tz("Europe/Amsterdam"))
'2023-10-29T02:00:00+01:00'

Workaround for now -- check the timezone before converting.

I assume the issue is here: https://github.com/sdispater/pendulum/blob/master/src/pendulum/datetime.py#L355C10-L355C10

gibsondan commented 1 year ago

Looks like this stems from always using dst_rule=pendulum.POST_TRANSITION in 2.1.2: https://github.com/sdispater/pendulum/blob/2.1/pendulum/datetime.py#L323

appears to actually be fixed in master (or at least that hard-coded dst_rule is not there anymore)

gibsondan commented 1 year ago

Confirmed that this is fixed in the 3.0 pre-release