0

I have a date formated like this: "Thu Jan 05 17:42:26 MST 2023" and need to change it to be formated like this: "2023-01-06T04:58:00Z".

I thought this would be really easy. Parse the date with datetime.datetime.strptime(), adjust the timezone with datetime.datetime.astimezone(pytz.utc) and output it with datetime.datetime.strftime().

On my machine running Python 3.10 it is that simple. Even though strptime discards timezone, astimezone(pytz.utc) still works for some reason and outputs the correct time format.

On the server, running Python 2.7 it throws "ValueError: astimezone() requires an aware datetime". So I slice the timezone out of the initial string and localize the datetime. Works great except pytz.timezone() cannot parse daylight savings timezones like MDT. I know there is a parameter for DST but then I have to manually parse the timezone string to figure out DST.

The only way I have gotten this work work properly is by making a dictionary of every timezone and their offsets, parsing the intial string into a epoch timestamp, applying the offset, then formatting back into my desired string.

What am I doing wrong? Why is this so insanely difficult?

# Works fine on Python 3.10 but returns error on Python 2.7
def _formatTimestamp1(timestamp):
    local_dt = datetime.strptime(str(timestamp), '%a %b %d %H:%M:%S %Z %Y')
    utc_dt = local_dt.astimezone(pytz.utc)
    fmt_dt = utc_dt.strftime("%Y-%m-%dT%H:%M:%SZ")
    return str(fmt_dt)

# Works good but pytz.timezone() cannot handle paring DST times like 'MDT'
def _formatTimestamp2(timestamp):
    local_dt = datetime.strptime(str(timestamp), '%a %b %d %H:%M:%S %Z %Y')
    timezone = pytz.timezone(timestamp[20:-5])
    aware = timezone.localize(local_dt)
    utc_dt = aware.astimezone(pytz.utc)
    fmt_dt = utc_dt.strftime("%Y-%m-%dT%H:%M:%SZ")
    return str(fmt_dt)

# So far this is the best method, but requires building a timezone database
def _formatTimestamp3(timestamp):
    tz_dict = {"MST":-7,"MDT":-6}
    local_dt = datetime.strptime(str(timestamp), '%a %b %d %H:%M:%S %Z %Y')
    utc_dt = datetime.fromtimestamp(local_dt.timestamp() - tz_dict[timestamp[20:-5]] * 60 * 60)
    fmt_dt = utc_dt.strftime("%Y-%m-%dT%H:%M:%SZ")
    return str(fmt_dt)
kgoodwin
  • 3
  • 2
  • It's insanely difficult because time zone support in Python wasn't well thought out in the beginning. – Mark Ransom Jan 06 '23 at 18:28
  • 1
    Also abbreviations like "MST" aren't unique world wide. – Mark Ransom Jan 06 '23 at 18:29
  • 1
    Parsing the abbreviated timezone name correctly is difficult due to ambiguity; dateutil parser [offers an option](https://stackoverflow.com/a/45990194/10197418). Basically you will have to define which abbreviated tz name maps to which IANA tz name (e.g. MST --> "America/Denver"). – FObersteiner Jan 06 '23 at 18:41

0 Answers0