Brad Davis
Brad Davis

Reputation: 1170

How can I convey text descriptions of location time zones to UTC based in Python?

I need to be able to convert a time zone stored as a string that is region based either to a UTC time zone or a common time zone across locations. For example, “Canada/Vancouver” and “Americas/Los_Angeles” should both resolve to “US/Pacific”. This solution should also work for other time zones like “Canada/Toronto” and “AmericA/New_York” to “US/Eastern”, also extending to time zones for other locations like Mexico, etc.

I have no idea how to do this or even think about this. I could convert it to a UTC-7 but that doesn’t handle PST vs PDT shifts.

Can someone help?

Edit: after reading the comments and answer I realized that my question wasn’t clear enough. I have a set of phone numbers, and I use the “phonenumbers” package to get the time zone out in the newer format for each number, but I want to count the number of unique phone numbers by the old region time zone naming convention. Hence I want to convert to newer “Continent/City” time zones to “Country/Region” time zones. . The UTC was just me trying to think of a way to convert the region/city formats into a common name.

Upvotes: 0

Views: 693

Answers (1)

FObersteiner
FObersteiner

Reputation: 25584

time zones as from the IANA database refer to regions in a geographical sense. UTC on the other hand is not a time zone, it is universal (not specific to a region).

  • For a time zone, you can have an offset from UTC (like UTC-8 for 8 hours behind UTC).
  • A certain date/time in a given time zone has a specific UTC offset, as derived from the rules for that time zone (when to apply DST etc.).
  • The other way around, a certain UTC offset can apply in multiple time zones at given date/time, so mapping back needs a definition, otherwise it's ambiguous.

Regarding the naming of time zones, "Continent/City"-style time zone names are preferred. Old names like "US/Pacific" (as from before 1993) are kept in the database for backwards-compatibility - see also eggert-tz/backward.

Python >= 3.9 supports IANA time zones with the standard library via the zoneinfo module. Using that, you can create aware datetime objects easily and get their UTC offset, e.g. like

from datetime import datetime
from zoneinfo import ZoneInfo

tznames = ["America/Vancouver", "America/Los_Angeles",
           "America/Toronto", "America/New_York", "Europe/Berlin"]

def timedelta_to_str(td):
    hours, seconds = divmod(td.total_seconds(), 3600)
    return f"{int(hours):+}:{int(seconds/60):02d}"

now = datetime.now().replace(microsecond=0)

for z in tznames:
    local_now = now.astimezone(ZoneInfo(z))
    print(f"now in zone {z}:\n\t{local_now.isoformat(' ', timespec='seconds')}, "
          f"UTC offset: {timedelta_to_str(local_now.utcoffset())} hours\n")
    # or also e.g. print(f"local time {z}:\n\t{local_now}, UTC offset: {local_now.strftime('%z')}\n")

# now in zone America/Vancouver:
#   2022-01-12 06:30:08-08:00, UTC offset: -08:00 hours

# now in zone America/Los_Angeles:
#   2022-01-12 06:30:08-08:00, UTC offset: -08:00 hours

# now in zone America/Toronto:
#   2022-01-12 09:30:08-05:00, UTC offset: -05:00 hours

# now in zone America/New_York:
#   2022-01-12 09:30:08-05:00, UTC offset: -05:00 hours

# now in zone Europe/Berlin:
#   2022-01-12 15:30:08+01:00, UTC offset: +01:00 hours

see also on SO:

Upvotes: 1

Related Questions