Search code examples
pythonpytz

Python & pytz: Figure out if a timezone supports DST and what the DST and non-DST UTC offsets are


I am using python 2.7.3 and pytz.

For a given timezone which describes a region (e.g. America/New_York), I would like to know if the timezone observes DST during part of the year or not. I care about the present timezone definition in effect. To rephrase the question, given the present timezone definition, will this timezone observer DST (or stop observing it) within the next 365 days?

Additionally, I would like to know what the offset from UTC is for this timezone when it is observing DST and what the offset is when it is not observing DST.

Finally, I would like to know whether or not a given timezone is presently observing DST.

The end goal is to generate a list like this:

Name                    Observes DST     DST Offset     non-DST Offset   Presently DST
--------------------------------------------------------------------------------------
America/New_York        Yes              6              5                No

I cannot figure out how to get this information from pytz.


Solution

  • I was able to solve this using this function:

    def get_tz_dst_info(tz):
        """
        Gets a 3-tuple of info about DST for a timezone. The returned elements are:
        - a boolean if this timezone observes DST
        - a Decimal UTC offset when not in DST
        - a Decimal UTC offset when in DST
    
        >>> from pytz import timezone
        >>> get_tz_dst_info(timezone('America/New_York'))
        (True, Decimal('-4'), Decimal('-5'))
        >>> get_tz_dst_info(timezone('Europe/Paris'))
        (True, Decimal('2'), Decimal('1'))
        >>> get_tz_dst_info(timezone('UTC'))
        (False, Decimal('0'), Decimal('0'))
        """
        dec_int_offset = timedelta_utc_offset_to_decimal(
            tz.utcoffset(DECEMBER_DATE)
        )
        jul_int_offset = timedelta_utc_offset_to_decimal(tz.utcoffset(JULY_DATE))
        jul_dst = tz.dst(JULY_DATE)
        dec_dst = tz.dst(DECEMBER_DATE)
    
        dst_offset = dec_int_offset
        non_dst_offset = jul_int_offset
        if jul_dst >= timedelta(seconds=0):
            dst_offset = jul_int_offset
            non_dst_offset = dec_int_offset
        elif dec_dst >= timedelta(seconds=0):
            dst_offset = jul_int_offset
            non_dst_offset = dec_int_offset
        return (dec_int_offset != jul_int_offset,
                non_dst_offset,
                dst_offset)