0

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.

Brad Davis
  • 1,063
  • 3
  • 18
  • 38
  • The package `pytz` can be of help. Do you have an example timestamp? – Hommes Jan 12 '22 at 08:24
  • I don’t want to do this with timestamp, I want to convert to newer “Continent/City” time zones to “Country/Region” time zones. I have a set of phone numbers, and I use the phone numbers package to get the time zone out in the newer format, but I want to count the number of unique phone numbers by the old region time zone naming convention. The UTC was just me trying to think of a way to convert the region/city formats into a common name. – Brad Davis Jan 12 '22 at 14:54

1 Answers1

1

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:

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • I don’t want to do this with timestamp, I want to convert to newer “Continent/City” time zones to “Country/Region” time zones. I have a set of phone numbers, and I use the”phonenumbers” package to get the time zone out in the newer format, but I want to count the number of unique phone numbers by the old region time zone naming convention. The UTC was just me trying to think of a way to convert the region/city formats into a common name. But I think I can do that with the eggertz-to/backward package. Thanks! – Brad Davis Jan 12 '22 at 15:08
  • @BradDavis then what about defining a time zone to region mapping? Or just use the UTC offset as "region"? If you have a date, I don't see a problem with this – FObersteiner Jan 12 '22 at 15:29
  • 1
    Yup, you are 100% correct. You helped me better understand the problem, thank you! – Brad Davis Jan 12 '22 at 16:20