Search code examples
pythontimezonepytz

What is a more elegant way of extracting timezone offsets in pytz?


I have a bit of code that uses datetime, pytz and re to determine the UTC offset of a given timezone, in the form of a datetime.timedelta object:

def get_utcoffset(mic, date):
    that_day = datetime.datetime.combine(date, datetime.time())
    tzone = pytz.timezone(timezones[mic]) # e.g. pytz.timezone("Asia/Tokyo")
    offset_string = tzone.localize(that_day).strftime("%z")
    pattern = "^(.)(\\d{2})(\\d{2})$"
    captured = re.search(pattern, offset_string)
    sign = captured.group(1)
    hh = int(captured.group(2))
    mm = int(captured.group(3))
    if sign == "-":
        return datetime.timedelta(hours=-hh, minutes=-mm)
    return datetime.timedelta(hours=hh, minutes=mm)

It looks like there should be a more elegant and efficient way of doing this, since the pytz.timezone.localize must be aware of its own offsets relative to UTC. It seems wasteful to extract the offset values as a string and then use regex to essentially sscanf the string.

How can we make this code better?


Solution

  • If you look at the documentation for Python tzinfo objects you'll see a method called utcoffset. This will give you the offset directly.

    delta = tzone.utcoffset(that_day)
    return delta
    

    Edit: no need to call localize on the datetime, The pytz object does it itself as part of utcoffset. It expects to be passed a naive datetime.