-
-
Notifications
You must be signed in to change notification settings - Fork 691
Description
Issue Description
Arrow's shift
function appears to handle daylight savings time incorrectly, or at least inconsistently. In particular, on spring-forward days, shifting forward by 2 hours from midnight is treated as being the same time as shifting 3 from midnight:
Python 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:41:52) [Clang 15.0.7 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import arrow
>>> from datetime import datetime
>>> x = arrow.get(datetime(2023, 3, 12), 'America/Los_Angeles')
>>> x.shift(hours=3) == x.shift(hours=2)
True
>>> print(x.shift(hours=2))
2023-03-12T03:00:00-07:00
>>> print(x.shift(hours=3))
2023-03-12T03:00:00-07:00
It looks to me like shifting by 2 hours is correct, but that shifting 3 is not. Perhaps this is the intended semantics of shift
, but if that's the case then the following example seems inconsistent (shifting by 1 hour 3 times returns the result I expected for shifting 3 hours once):
>>> x.shift(hours=1).shift(hours=1).shift(hours=1)
<Arrow [2023-03-12T04:00:00-07:00]>
>>> x.shift(hours=1).shift(hours=1).shift(hours=1) == x.shift(hours=3) # I'd expect this to be true for any value of x
False
When I try adding timedelta(hours=1)
I get different unintuitive behavior, this time when it comes to adding 1 hour or 2 hours:
>>> (x + timedelta(hours=1)).timestamp() == (x + timedelta(hours=2)).timestamp() # I'd expect this to be false
True
>>> x + timedelta(hours=1)
<Arrow [2023-03-12T01:00:00-08:00]> # this looks right to me
>>> x + timedelta(hours=2)
<Arrow [2023-03-12T02:00:00-07:00]> # I think this should be 2023-03-12T03:00:00-07:00
On fall-behind days, there are also problems. In this case using both shift
and adding a timedelta
do the same thing : the gap between midnight offsetby 1 hour and offset by 2 hours is 7200 seconds (2 hours):
>>> y = arrow.get(datetime(2023, 11, 5), 'America/Los_Angeles')
>>> y.shift(hours=1)
<Arrow [2023-11-05T01:00:00-07:00]>
>>> y.shift(hours=2)
<Arrow [2023-11-05T02:00:00-08:00]>
>>> y.shift(hours=2).timestamp() - y.shift(hours=1).timestamp() # I'd expect 3600
7200.0
>>> (y + timedelta(hours=2)).timestamp() - (y + timedelta(hours=1)).timestamp() # I'd expect 3600
7200.0
System Info
- 🖥 OS name and version: macOs 14.2.1
- 🐍 Python version: 3.10.12
- 🏹 Arrow version: 1.3.0