How to convert a timezone aware string to datetime in Python without dateutil?
As of Python 3.7, datetime.datetime.fromisoformat()
can handle your format:
>>> import datetime
>>> datetime.datetime.fromisoformat('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
In older Python versions you can't, not without a whole lot of painstaking manual timezone defining.
Python does not include a timezone database, because it would be outdated too quickly. Instead, Python relies on external libraries, which can have a far faster release cycle, to provide properly configured timezones for you.
As a side-effect, this means that timezone parsing also needs to be an external library. If dateutil
is too heavy-weight for you, use iso8601
instead, it'll parse your specific format just fine:
>>> import iso8601
>>> iso8601.parse_date('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=<FixedOffset '-04:00'>)
iso8601
is a whopping 4KB small. Compare that tot python-dateutil
's 148KB.
As of Python 3.2 Python can handle simple offset-based timezones, and %z
will parse -hhmm
and +hhmm
timezone offsets in a timestamp. That means that for a ISO 8601 timestamp you'd have to remove the :
in the timezone:
>>> from datetime import datetime
>>> iso_ts = '2012-11-01T04:16:13-04:00'
>>> datetime.strptime(''.join(iso_ts.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))
The lack of proper ISO 8601 parsing is being tracked in Python issue 15873.
How to make a timezone aware datetime object
In general, to make a naive datetime timezone-aware, use the localize method:
import datetime
import pytz
unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)
now_aware = pytz.utc.localize(unaware)
assert aware == now_aware
For the UTC timezone, it is not really necessary to use localize
since there is no daylight savings time calculation to handle:
now_aware = unaware.replace(tzinfo=pytz.UTC)
works. (.replace
returns a new datetime; it does not modify unaware
.)
Convert non-ISO string containing date, time and timezone to UTC datetime
You can use datetime.datetime.strptime
which, %z
recognizes timezones without ":" or if using a 3rd party library is more appealing, python-dateutil dateutil.parse.isoparse
works straight out of the box. Timezone conversion is afterwards easy with .astimezone
method:
import datetime
import dateutil.parser
date_str = "2021-12-15T20:40:39.718-0500"
dt = datetime.datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%f%z")
print(dt)
# Alternative with dateutil
dt = dateutil.parser.isoparse(date_str)
print(dt)
dt = dt.astimezone(datetime.timezone.utc)
print(dt)
Python Datetime : use strftime() with a timezone-aware date
In addition to what @Slam has already answered:
If you want to output the UTC time without any offset, you can do
from datetime import timezone, datetime, timedelta
d = datetime(2009, 4, 19, 21, 12, tzinfo=timezone(timedelta(hours=-2)))
d.astimezone(timezone.utc).strftime('%Y-%m-%d %H:%M:%S.%f')
See datetime.astimezone in the Python docs.
convert string having timezone into to utc datetime object python
That looks like an ISO 8601 string (though with anomalously high precision on the sub-second component); if the fact that you have 7 digits instead of 6 after the decimal point is a typo, you can use dateutil.parser.isoparse
on it:
from dateutil.parser import isoparse
from dateutil.tz import UTC
dt = isoparse('2018-05-04T05:22:52.327261-04:00')
dt.astimezone(UTC)
Otherwise you can use dateutil.parser.parse
, which is slower but allows for more unusual formats:
from dateutil.parser import parse
from dateutil.tz import UTC
dt = parse('2018-05-04T05:22:52.3272611-04:00')
dt.astimezone(UTC)
You should also use parse
if you are not certain what the format will be.
how to convert a string datetime with unknown timezone to timestamp in python
Short answer, without using tzinfos, replace CDT with its UTC equivalent:
In [15]: from dateutil import parser
...: timestamp = parser.parse("Thu Jun 02 11:56:53 UTC-5 2011")
...:
...:
In [16]: timestamp
Out[16]: datetime.datetime(2011, 6, 2, 11, 56, 53, tzinfo=tzoffset(None, 18000))
You can use tzinfos, it must be a dict where keys are the unknows timezones and values are either string UTC format (UTC-5 for example) or number of seconds to offset, here is the doc:
TZINFOS
Additional time zone names / aliases which may be present in the
string. This argument maps time zone names (and optionally offsets
from those time zones) to time zones. This parameter can be a
dictionary with timezone aliases mapping time zone names to time zones
or a function taking two parameters (tzname and tzoffset) and
returning a time zone. The timezones to which the names are mapped can
be an integer offset from UTC in seconds or a tzinfo object. This
parameter is ignored if ignoretz is set.
I tried with both methods and compared
timestamp = parser.parse("Thu Jun 02 11:56:53 CDT 2011", tzinfos={"CDT": -5*3600})
timestamp2 = parser.parse("Thu Jun 02 11:56:53 CDT 2011", tzinfos={"CDT": "UTC-5"})
timestamp3 = parser.parse("Thu Jun 02 11:56:53 UTC-0500 2011")
and it prints
2011-06-02 11:56:53-05:00
2011-06-02 11:56:53-05:00
2011-06-02 11:56:53+05:00
it seems like you have to inverse the sign when using tzinfos (correct me, it might be the inverse thing to do)
How can I parse a custom string as a timezone aware datetime?
Hmm How about maybe:
import re
import datetime
foo = "18 January 2022, 14:50 GMT-5"
bar = re.sub(r"[+-]\d+$", lambda m: "{:05d}".format(100 * int(m.group())), foo)
print(datetime.datetime.strptime(bar, "%d %B %Y, %H:%M %Z%z" ))
I think that gives you:
2022-01-18 14:50:00-05:00
Related Topics
Configuring So That Pip Install Can Work from Github
Sorting by a Custom List in Pandas
How to Handle a Broken Pipe (Sigpipe) in Python
Check What Files Are Open in Python
Running a Process in Pythonw with Popen Without a Console
Find Maximum Value of a Column and Return the Corresponding Row Values Using Pandas
Thread Safety in Python's Dictionary
Pandas Out of Bounds Nanosecond Timestamp After Offset Rollforward Plus Adding a Month Offset
Super() Raises "Typeerror: Must Be Type, Not Classobj" for New-Style Class
Pandas Dataframe Concat VS Append
How to Parse a Website Using Selenium and Beautifulsoup in Python
Django Aggregation: Summation of Multiplication of Two Fields
What Is a '"Python"' Layer in Caffe
How to Check If Directory Exists in Python
How to Specify Your Own Distance Function Using Scikit-Learn K-Means Clustering