physio
physio

Reputation: 129

Unable to convert datetime string with timezone to datetime in UTC using datetime python module

I am having issues converting a datetime string of this format "%d %b %Y %X %Z" to "%Y-%m-%dT%X%z". The timezone information is stripped out. For example:

>> import datetime
>> datetime_string_raw = "18 Nov 2022 08:57:04 EST" 
>> datetime_utc =  datetime.datetime.strptime(datetime_string_raw, "%d %b %Y %X %Z").strftime("%Y-%m-%dT%X%z")
>> print(datetime_utc)
2022-11-18T08:57:04

How can I get it to print the UTC offset? Why doesn't the %Z and %z have any effect? Thanks!

Upvotes: 0

Views: 114

Answers (1)

FObersteiner
FObersteiner

Reputation: 25564

Using dateutil's parser and a definition which abbreviated names should resemble which time zone:

import datetime
import dateutil # pip install python-dateutil

tzinfos = {"EST": dateutil.tz.gettz("America/New_York"),
           "EDT": dateutil.tz.gettz("America/New_York")}

datetime_string_raw = "18 Nov 2022 08:57:04 EST" 

datetime_ny = dateutil.parser.parse(datetime_string_raw, tzinfos=tzinfos)
print(datetime_ny)
# 2022-11-18 08:57:04-05:00

datetime_utc = datetime_ny.astimezone(datetime.timezone.utc)
print(datetime_utc)
# 2022-11-18 13:57:04+00:00

You can do basically the same using only the standard library, but it requires some pre-processing of the date/time string. Ex:

import datetime
import zoneinfo # Python >= 3.9

def parse_dt_with_tz(dt_string: str, fmt: str, tzinfos: dict) -> datetime.datetime:
    """Parse date/time string with abbreviated time zone name to aware datetime."""
    parts = dt_string.split(" ")
    tz = tzinfos.get(parts[-1]) # last element is the tz name
    if not tz:
        raise ValueError(f"no entry found for {parts[-1]} in tzinfos")
    return datetime.datetime.strptime(" ".join(parts[:-1]), fmt).replace(tzinfo=tz)

# usage
tzinfos = {"EST": zoneinfo.ZoneInfo("America/New_York"),
           "EDT": zoneinfo.ZoneInfo("America/New_York")}

s = "18 Nov 2022 08:57:04 EST"
dt = parse_dt_with_tz(s, "%d %b %Y %H:%M:%S", tzinfos)
print(dt, repr(dt))
# 2022-11-18 08:57:04-05:00 datetime.datetime(2022, 11, 18, 8, 57, 4, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))

Upvotes: 1

Related Questions