(transitionTo, year, tzinfo)
Return the datetime of the transition to/from DST, or None.
Return the datetime of the transition to/from DST, or None.
Return the datetime of the transition to / from DST or None .
def getTransition(transitionTo, year, tzinfo):
    """
    Return the datetime of the transition to/from DST, or None.
    """
    def firstTransition(iterDates, test):
        """
        Return the last date not matching test, or None if all tests matched.
        """
        success = None
        for dt in iterDates:
            if not test(dt):
                success = dt
            else:
                if success is not None:
                    return success
        return success # may be None

    def generateDates(year, month=None, day=None):
        """
        Iterate over possible dates with unspecified values.
        """
        months = range(1, 13)
        days   = range(1, 32)
        hours  = range(0, 24)
        if month is None:
            for month in months:
                yield datetime.datetime(year, month, 1)
        elif day is None:
            for day in days:
                try:
                    yield datetime.datetime(year, month, day)
                except ValueError:
                    pass
        else:
            for hour in hours:
                yield datetime.datetime(year, month, day, hour)

    assert transitionTo in ('daylight', 'standard')
    if transitionTo == 'daylight':
        def test(dt):
            try:
                return tzinfo.dst(dt) != zeroDelta
            except pytz.NonExistentTimeError:
                return True  # entering daylight time
            except pytz.AmbiguousTimeError:
                return False  # entering standard time
    elif transitionTo == 'standard':
        def test(dt):
            try:
                return tzinfo.dst(dt) == zeroDelta
            except pytz.NonExistentTimeError:
                return False  # entering daylight time
            except pytz.AmbiguousTimeError:
                return True  # entering standard time
    newyear = datetime.datetime(year, 1, 1)
    monthDt = firstTransition(generateDates(year), test)
    if monthDt is None:
        return newyear
    elif monthDt.month == 12:
        return None
    else:
        # there was a good transition somewhere in a non-December month
        month = monthDt.month
        day         = firstTransition(generateDates(year, month), test).day
        uncorrected = firstTransition(generateDates(year, month, day), test)
        if transitionTo == 'standard':
            # assuming tzinfo.dst returns a new offset for the first
            # possible hour, we need to add one hour for the offset change
            # and another hour because firstTransition returns the hour
            # before the transition
            return uncorrected + datetime.timedelta(hours=2)
        else:
            return uncorrected + datetime.timedelta(hours=1)
def getTransition ( transitionTo , year , tzinfo ) : def firstTransition ( iterDates , test ) : """
        Return the last date not matching test, or None if all tests matched.
        """ success = None for dt in iterDates : if not test ( dt ) : success = dt else : if success is not None : return success return success # may be None def generateDates ( year , month = None , day = None ) : """
        Iterate over possible dates with unspecified values.
        """ months = range ( 1 , 13 ) days = range ( 1 , 32 ) hours = range ( 0 , 24 ) if month is None : for month in months : yield datetime . datetime ( year , month , 1 ) elif day is None : for day in days : try : yield datetime . datetime ( year , month , day ) except ValueError : pass else : for hour in hours : yield datetime . datetime ( year , month , day , hour ) assert transitionTo in ( 'daylight' , 'standard' ) if transitionTo == 'daylight' : def test ( dt ) : try : return tzinfo . dst ( dt ) != zeroDelta except pytz . NonExistentTimeError : return True # entering daylight time except pytz . AmbiguousTimeError : return False # entering standard time elif transitionTo == 'standard' : def test ( dt ) : try : return tzinfo . dst ( dt ) == zeroDelta except pytz . NonExistentTimeError : return False # entering daylight time except pytz . AmbiguousTimeError : return True # entering standard time newyear = datetime . datetime ( year , 1 , 1 ) monthDt = firstTransition ( generateDates ( year ) , test ) if monthDt is None : return newyear elif monthDt . month == 12 : return None else : # there was a good transition somewhere in a non-December month month = monthDt . month day = firstTransition ( generateDates ( year , month ) , test ) . day uncorrected = firstTransition ( generateDates ( year , month , day ) , test ) if transitionTo == 'standard' : # assuming tzinfo.dst returns a new offset for the first # possible hour, we need to add one hour for the offset change # and another hour because firstTransition returns the hour # before the transition return uncorrected + datetime . timedelta ( hours = 2 ) else : return uncorrected + datetime . timedelta ( hours = 1 )