-
-
Notifications
You must be signed in to change notification settings - Fork 704
Description
Issue Description
It looks like arrow is doing something weird timezone information when operating datetime objects, including datetime objects returned by e.g. dateparser.parse('now').
What is the appropriate incantation to get arrow and datetime to agree? I've managed to do it in one of my projects by using epochseconds, but would prefer to keep my dates as either datetime or arrow object representations.
I am in central standard time, so the "6 hours ago" seems to reflect my TZ offset from UTC, but even providing a ..., tzinfo= does not appear to do the correct thing.
Overall, the mixture of simple things that don't work is overwhelming, and there should maybe be some examples in the documentation for how to do this right (e.g. setting tzinfo on the datetime object makes arrow's object correct, but setting tzinfo on the arrow object does not).
date(1) vs datetime
As best I can tell, datetime.now() is correct, and lacks a specific timezone.
>>> import datetime, subprocess
>>> datetime.datetime.now()
datetime.datetime(2021, 3, 9, 19, 55, 36, 539945)
>>> subprocess.check_output('date', text=True)
'Tue Mar 9 19:55:39 CST 2021\n'datetime vs arrow
This jives with the 6 hour time difference from UTC, but why does it say "6 hours ago"? Neither arrow nor datetime were provided with a timezone, so this seems odd.
>>> import arrow, datetime
>>> arrow.get(datetime.datetime.now()).humanize()
'6 hours ago'datetime with tzinfo
This happens even with a custom timezone, unless the timezone is specified on the datetime object.
>>> import arrow, dateparser, dateutil, datetime
>>> tz = dateutil.tz.tzlocal()
# With the local timezone on arrow.get() does NOT work
>>> arrow.get(datetime.datetime.now(), tzinfo=tz).humanize()
'6 hours ago'
# With the local timezone on datetime.now() DOES work
>>> arrow.get(datetime.datetime.now(tz=tz)).humanize()
'just now'
# With a custom timezone (set to be GMT-6)
>>> mytz = dateutil.tz.tzoffset('MyTZ', datetime.timedelta(hours=6))
>>> mytz
tzoffset('MyTZ', 21600)
>>> arrow.get(datetime.datetime.now(), tzinfo=mytz).humanize()
'6 hours ago'dateparser
Per the documentation:
dateparser relies on following libraries in some ways:
• tzlocal to reliably get local timezone.
However, this doesn't seem to work correctly either.
>>> import arrow, dateparser
>>> arrow.get(dateparser.parse('now')).humanize()
'6 hours ago'dateparser with tzinfo
This happens regardless of whether tzinfo is specified.
>>> import arrow, dateparser, dateutil
>>> tz = dateutil.tz.tzlocal()
>>> tz
tzlocal()
>>> arrow.get(dateparser.parse('now'), tzinfo=tz).humanize()
'6 hours ago'Unix Timestamps
It looks like there's an issue with timestamps as well. If I pass the timestamp directly to arrow.get(), it returns the correct value.
>>> dt = datetime.datetime.fromtimestamp(1615341484)
>>> dt
datetime.datetime(2021, 3, 9, 19, 58, 4)
>>> !date
Tue Mar 9 20:02:38 CST 2021
# We can see that arrow is correct in its humanize()
>>> arrow.get(1615341484).humanize()
'4 minutes ago'
# However, using the datetime derived from the timestamp exhibits the same issue
>>> arrow.get(dt).humanize()
'6 hours ago'System Info
$ sw_vers
ProductName: macOS
ProductVersion: 11.3
BuildVersion: 20E5172h
$ python3 --version
Python 3.8.2
$ python3 -m pip freeze | grep arrow
arrow==1.0.3