Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incorrect behavior WRT daylight savings for shift/adding timedelta #1170

Open
eigenvariable opened this issue Jan 25, 2024 · 0 comments
Open
Labels

Comments

@eigenvariable
Copy link

eigenvariable commented Jan 25, 2024

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant