def test_expand_date_tuple(self): self.assertEqual( (DateTuple(2000, 1, 30, 10800, 'w'), DateTuple(2000, 1, 30, 7200, 's'), DateTuple(2000, 1, 30, 0, 'u')), ZoneSpecifier._expand_date_tuple(DateTuple(2000, 1, 30, 10800, 'w'), offset_seconds=7200, delta_seconds=3600)) self.assertEqual( (DateTuple(2000, 1, 30, 10800, 'w'), DateTuple(2000, 1, 30, 7200, 's'), DateTuple(2000, 1, 30, 0, 'u')), ZoneSpecifier._expand_date_tuple(DateTuple(2000, 1, 30, 7200, 's'), offset_seconds=7200, delta_seconds=3600)) self.assertEqual( (DateTuple(2000, 1, 30, 10800, 'w'), DateTuple(2000, 1, 30, 7200, 's'), DateTuple(2000, 1, 30, 0, 'u')), ZoneSpecifier._expand_date_tuple(DateTuple(2000, 1, 30, 0, 'u'), offset_seconds=7200, delta_seconds=3600))
def estimate(self): """Calculate the (dict) of {full_name -> buf_size} where buf_size is one more than the estimate from ZoneSpecifier.get_buffer_sizes(). Return the tuple of (buf_sizes, max_size). """ buf_sizes = {} max_size = 0 for zone_name, zone_info in self.zone_infos.items(): zone_specifier = ZoneSpecifier(zone_info) (max_actives, max_buffer_size) = zone_specifier.get_buffer_sizes( self.start_year, self.until_year) # The TransitionStorage size should be one more than the estimate # because TransitionStorage.getFreeAgent() needs one slot even if # it's not used. buf_size = max_buffer_size[0] + 1 # The estimate is off for Asia/Atyrau. zone_specifier.py returns # max_buffer_size[0]==4 which means 5 should be enough, but # TransitionStorage.getHighWater() says that 6 is required. Not sure # why. if zone_name == 'Asia/Atyrau': buf_size += 1 buf_sizes[zone_name] = buf_size if buf_size > max_size: max_size = buf_size return (buf_sizes, max_size)
def test_Istanbul(self): """Europe/Istanbul uses an 'hh:mm' offset in the RULES field in 2015. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Europe_Istanbul, viewing_months=14) zone_specifier.init_for_year(2015) matches = zone_specifier.matches self.assertEqual(3, len(matches)) self.assertEqual(DateTuple(2014, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2015, 10, 25, 1 * 3600, 'u'), matches[0].untilDateTime) self.assertEqual('EU', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2015, 10, 25, 1 * 3600, 'u'), matches[1].startDateTime) self.assertEqual(DateTuple(2015, 11, 8, 1 * 3600, 'u'), matches[1].untilDateTime) self.assertEqual(':', matches[1].zoneEra.policyName) self.assertEqual(DateTuple(2015, 11, 8, 1 * 3600, 'u'), matches[2].startDateTime) self.assertEqual(DateTuple(2016, 2, 1, 0, 'w'), matches[2].untilDateTime) self.assertEqual('EU', matches[2].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(4, len(transitions)) self.assertEqual(DateTuple(2014, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2015, 3, 29, 3 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(2 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2015, 3, 29, 4 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2015, 10, 25, 4 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(2 * 3600, transitions[1].offsetSeconds) self.assertEqual(1 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2015, 10, 25, 4 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2015, 11, 8, 4 * 3600, 'w'), transitions[2].untilDateTime) self.assertEqual(2 * 3600, transitions[2].offsetSeconds) self.assertEqual(1 * 3600, transitions[2].deltaSeconds) self.assertEqual(DateTuple(2015, 11, 8, 3 * 3600, 'w'), transitions[3].startDateTime) self.assertEqual(DateTuple(2016, 2, 1, 0, 'w'), transitions[3].untilDateTime) self.assertEqual(2 * 3600, transitions[3].offsetSeconds) self.assertEqual(0 * 3600, transitions[3].deltaSeconds)
def test_zone_specifier_using_validation_data(self): for name, items in zonedb.validation_data.VALIDATION_DATA.items(): zone_info = zonedb.zone_infos.ZONE_INFO_MAP[name] zone_specifier = ZoneSpecifier(zone_info, viewing_months=14) for item in items: info = zone_specifier.get_timezone_info_for_seconds(item.epoch) self.assertEqual( item.total_offset * 60, info.total_offset, ('Zone %s; epoch:%s; %04d-%02d-%02d %02d:%02d:%02d' % (name, item.epoch, item.y, item.M, item.d, item.h, item.m, item.s)))
def test_Apia(self): """Pacific/Apia uses a transition time of 24:00 on Dec 29, 2011, going from Thursday 29th December 2011 23:59:59 Hours to Saturday 31st December 2011 00:00:00 Hours. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Pacific_Apia, viewing_months=14) zone_specifier.init_for_year(2011) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2010, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2011, 12, 29, 24 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('WS', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2011, 12, 29, 24 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2012, 2, 1, 0, 'w'), matches[1].untilDateTime) self.assertEqual('WS', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(4, len(transitions)) self.assertEqual(DateTuple(2010, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2011, 4, 2, 4 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(-11 * 3600, transitions[0].offsetSeconds) self.assertEqual(1 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2011, 4, 2, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2011, 9, 24, 3 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(-11 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2011, 9, 24, 4 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2011, 12, 30, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(-11 * 3600, transitions[2].offsetSeconds) self.assertEqual(1 * 3600, transitions[2].deltaSeconds) self.assertEqual(DateTuple(2011, 12, 31, 0 * 3600, 'w'), transitions[3].startDateTime) self.assertEqual(DateTuple(2012, 2, 1, 0, 'w'), transitions[3].untilDateTime) self.assertEqual(13 * 3600, transitions[3].offsetSeconds) self.assertEqual(1 * 3600, transitions[3].deltaSeconds)
def test_Simferopol(self): """Asia/Simferopol in 2014 uses a bizarre mixture of 'w' when using EU rules (which itself uses 'u' in the UNTIL fields), then uses 's' time to switch to Moscow time. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Europe_Simferopol, viewing_months=14) zone_specifier.init_for_year(2014) matches = zone_specifier.matches self.assertEqual(3, len(matches)) self.assertEqual(DateTuple(2013, 12, 1, 0 * 3600, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2014, 3, 30, 2 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('EU', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2014, 3, 30, 2 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2014, 10, 26, 2 * 3600, 's'), matches[1].untilDateTime) self.assertEqual('-', matches[1].zoneEra.policyName) self.assertEqual(DateTuple(2014, 10, 26, 2 * 3600, 's'), matches[2].startDateTime) self.assertEqual(DateTuple(2015, 2, 1, 0 * 3600, 'w'), matches[2].untilDateTime) self.assertEqual('-', matches[2].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(3, len(transitions)) self.assertEqual(DateTuple(2013, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2014, 3, 30, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(2 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2014, 3, 30, 4 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2014, 10, 26, 2 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(4 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2014, 10, 26, 1 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2015, 2, 1, 0 * 3600, 'w'), transitions[2].untilDateTime) self.assertEqual(3 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds)
def test_Winnipeg(self): """America/Winnipeg uses 'Rule Winn' until 2006 which has an 's' suffix in the Rule.AT field. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_America_Winnipeg, viewing_months=14) zone_specifier.init_for_year(2005) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2004, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2006, 1, 1, 0 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('Winn', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2006, 1, 1, 0 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2006, 2, 1, 0 * 3600, 'w'), matches[1].untilDateTime) self.assertEqual('Canada', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(4, len(transitions)) self.assertEqual(DateTuple(2004, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2005, 4, 3, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(-6 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2005, 4, 3, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2005, 10, 30, 3 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(-6 * 3600, transitions[1].offsetSeconds) self.assertEqual(1 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2005, 10, 30, 2 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2006, 1, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(-6 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds) self.assertEqual(DateTuple(2006, 1, 1, 0 * 3600, 'w'), transitions[3].startDateTime) self.assertEqual(DateTuple(2006, 2, 1, 0, 'w'), transitions[3].untilDateTime) self.assertEqual(-6 * 3600, transitions[3].offsetSeconds) self.assertEqual(0 * 3600, transitions[3].deltaSeconds)
def test_Santo_Domingo(self): """America/Santo_Domingo uses 2 ZoneEra changes in year 2000. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_America_Santo_Domingo, viewing_months=14) zone_specifier.init_for_year(2000) matches = zone_specifier.matches self.assertEqual(3, len(matches)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2000, 10, 29, 2 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('-', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2000, 10, 29, 2 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2000, 12, 3, 1 * 3600, 'w'), matches[1].untilDateTime) self.assertEqual('US', matches[1].zoneEra.policyName) self.assertEqual(DateTuple(2000, 12, 3, 1 * 3600, 'w'), matches[2].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), matches[2].untilDateTime) self.assertEqual('-', matches[2].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(3, len(transitions)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2000, 10, 29, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(-4 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2000, 10, 29, 1 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2000, 12, 3, 1 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(-5 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2000, 12, 3, 2 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(-4 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds)
def test_Moncton(self): """America/Moncton transitioned DST at 00:01 through 2006. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_America_Moncton, viewing_months=14) zone_specifier.init_for_year(2006) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2005, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2007, 1, 1, 0 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('Moncton', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2007, 1, 1, 0 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2007, 2, 1, 0, 'w'), matches[1].untilDateTime) self.assertEqual('Canada', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(4, len(transitions)) self.assertEqual(DateTuple(2005, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2006, 4, 2, 0 * 3600 + 60, 'w'), transitions[0].untilDateTime) self.assertEqual(-4 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2006, 4, 2, 1 * 3600 + 60, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2006, 10, 29, 0 * 3600 + 60, 'w'), transitions[1].untilDateTime) self.assertEqual(-4 * 3600, transitions[1].offsetSeconds) self.assertEqual(1 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2006, 10, 28, 23 * 3600 + 60, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2007, 1, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(-4 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds) self.assertEqual(DateTuple(2007, 1, 1, 0 * 3600, 'w'), transitions[3].startDateTime) self.assertEqual(DateTuple(2007, 2, 1, 0, 'w'), transitions[3].untilDateTime) self.assertEqual(-4 * 3600, transitions[3].offsetSeconds) self.assertEqual(0 * 3600, transitions[3].deltaSeconds)
def test_normalize_date_tuple(self): self.assertEqual( DateTuple(2000, 2, 1, 0, 'w'), ZoneSpecifier._normalize_date_tuple(DateTuple(2000, 2, 1, 0, 'w'))) self.assertEqual( DateTuple(2000, 2, 1, 0, 's'), ZoneSpecifier._normalize_date_tuple( DateTuple(2000, 1, 31, 24 * 3600, 's'))) self.assertEqual( DateTuple(2000, 2, 29, 23 * 3600, 'u'), ZoneSpecifier._normalize_date_tuple( DateTuple(2000, 3, 1, -3600, 'u')))
def test_Petersburg(self): """America/Indianapolis/Petersbug moved from central to eastern time in 1977, then switched back in 2006, then switched back again in 2007. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_America_Indiana_Petersburg, viewing_months=14) zone_specifier.init_for_year(2006) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2005, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2006, 4, 2, 2 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('-', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2006, 4, 2, 2 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2007, 2, 1, 0, 'w'), matches[1].untilDateTime) self.assertEqual('US', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(3, len(transitions)) self.assertEqual(DateTuple(2005, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2006, 4, 2, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(-5 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2006, 4, 2, 2 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2006, 10, 29, 2 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(-6 * 3600, transitions[1].offsetSeconds) self.assertEqual(1 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2006, 10, 29, 1 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2007, 2, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(-6 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds)
def test_Macquarie(self): """Antarctica/Macquarie changes ZoneEra in 2011 using a 'w' time, but the ZoneRule transitions use an 's' time, which happens to coincide with the change in ZoneEra. The code must treat those 2 transition times as the same point in time. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Antarctica_Macquarie, viewing_months=14) zone_specifier.init_for_year(2010) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2009, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2010, 4, 4, 3 * 3600, 'w'), matches[0].untilDateTime) self.assertEqual('AT', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2010, 4, 4, 3 * 3600, 'w'), matches[1].startDateTime) self.assertEqual(DateTuple(2011, 2, 1, 0, 'w'), matches[1].untilDateTime) self.assertEqual('-', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(2, len(transitions)) self.assertEqual(DateTuple(2009, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2010, 4, 4, 3 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(10 * 3600, transitions[0].offsetSeconds) self.assertEqual(1 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2010, 4, 4, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2011, 2, 1, 0 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(11 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds)
def _create_test_data_for_zone(self, zone_name, zone_info): """Create the TestItems for a specific zone. """ zone_specifier = ZoneSpecifier(zone_info) try: tz = pytz.timezone(zone_name) except: logging.error("Zone '%s' not found in Python pytz package", zone_name) return None return self._create_transition_test_items( zone_name, tz, zone_specifier)
def test_Los_Angeles(self): """America/Los_Angela uses a simple US rule. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_America_Los_Angeles, viewing_months=14) zone_specifier.init_for_year(2000) matches = zone_specifier.matches self.assertEqual(1, len(matches)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), matches[0].untilDateTime) self.assertEqual('US', matches[0].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(3, len(transitions)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2000, 4, 2, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(-8 * 3600, transitions[0].offsetSeconds) self.assertEqual(0, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2000, 4, 2, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2000, 10, 29, 2 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(-8 * 3600, transitions[1].offsetSeconds) self.assertEqual(1 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2000, 10, 29, 1 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(-8 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds)
def test_Dublin(self): """Europe/Dublin uses negative DST during Winter. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Europe_Dublin, viewing_months=14) zone_specifier.init_for_year(2000) matches = zone_specifier.matches self.assertEqual(1, len(matches)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), matches[0].untilDateTime) self.assertEqual('Eire', matches[0].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(3, len(transitions)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2000, 3, 26, 1 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(1 * 3600, transitions[0].offsetSeconds) self.assertEqual(-1 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2000, 3, 26, 2 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2000, 10, 29, 2 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(1 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2000, 10, 29, 1 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(1 * 3600, transitions[2].offsetSeconds) self.assertEqual(-1 * 3600, transitions[2].deltaSeconds)
def test_London(self): """Europe/London uses a EU which has a 'u' in the AT field. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Europe_London, viewing_months=14) zone_specifier.init_for_year(2000) matches = zone_specifier.matches self.assertEqual(1, len(matches)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), matches[0].untilDateTime) self.assertEqual('EU', matches[0].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(3, len(transitions)) self.assertEqual(DateTuple(1999, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2000, 3, 26, 1 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(0 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2000, 3, 26, 2 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2000, 10, 29, 2 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(0 * 3600, transitions[1].offsetSeconds) self.assertEqual(1 * 3600, transitions[1].deltaSeconds) self.assertEqual(DateTuple(2000, 10, 29, 1 * 3600, 'w'), transitions[2].startDateTime) self.assertEqual(DateTuple(2001, 2, 1, 0, 'w'), transitions[2].untilDateTime) self.assertEqual(0 * 3600, transitions[2].offsetSeconds) self.assertEqual(0 * 3600, transitions[2].deltaSeconds)
def test_Kamchatka(self): """Asia/Kamchatka uses 's' in the Zone UNTIL and Rule AT fields. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Asia_Kamchatka, viewing_months=14) zone_specifier.init_for_year(2011) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2010, 12, 1, 0 * 3600, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2011, 3, 27, 2 * 3600, 's'), matches[0].untilDateTime) self.assertEqual('Russia', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2011, 3, 27, 2 * 3600, 's'), matches[1].startDateTime) self.assertEqual(DateTuple(2012, 2, 1, 0 * 3600, 'w'), matches[1].untilDateTime) self.assertEqual('-', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(2, len(transitions)) self.assertEqual(DateTuple(2010, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2011, 3, 27, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(11 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2011, 3, 27, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2012, 2, 1, 0 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(12 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds)
def validate_buffer_size(self): """Find the maximum number of actual transitions and the maximum number of candidate transitions required for each zone, across a range of years. """ # map of {zoneName -> (numTransitions, year)} transition_stats = {} # If 'self.year' is defined, clobber the range of validation years. if self.year: self.start_year = self.year self.until_year = self.year + 1 logging.info('Calculating transitions from [%s, %s)' % (self.start_year, self.until_year)) # Calculate the buffer sizes for every Zone in zone_infos. for zone_name, zone_info in sorted(self.zone_infos.items()): if self.zone_name and zone_name != self.zone_name: continue if self.debug_validator: logging.info('Validating zone %s' % zone_name) zone_specifier = ZoneSpecifier( zone_info_data=zone_info, viewing_months=self.viewing_months, debug=self.debug_specifier, in_place_transitions=self.in_place_transitions, optimize_candidates=self.optimize_candidates) transition_stats[zone_name] = zone_specifier.get_buffer_sizes( self.start_year, self.until_year) logging.info('Zone Name: #NumTransitions (year); #MaxBufSize (year)') for zone_name, count_record in sorted( transition_stats.items(), key=lambda x: x[1], reverse=True): logging.info( '%s: %d (%04d); %d (%04d)' % ((zone_name, ) + count_record[0] + count_record[1]))
def test_Famagusta(self): """Asia/Famagusta uses 'u' in the Zone UNTIL field. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Asia_Famagusta, viewing_months=14) zone_specifier.init_for_year(2017) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2016, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2017, 10, 29, 1 * 3600, 'u'), matches[0].untilDateTime) self.assertEqual('-', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2017, 10, 29, 1 * 3600, 'u'), matches[1].startDateTime) self.assertEqual(DateTuple(2018, 2, 1, 0, 'w'), matches[1].untilDateTime) self.assertEqual('EUAsia', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(2, len(transitions)) self.assertEqual(DateTuple(2016, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2017, 10, 29, 4 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(3 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2017, 10, 29, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2018, 2, 1, 0 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(2 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds)
def test_Moscow(self): """Europe/Moscow uses 's' in the Zone UNTIL field. """ zone_specifier = ZoneSpecifier( zonedb.zone_infos.ZONE_INFO_Europe_Moscow, viewing_months=14) zone_specifier.init_for_year(2011) matches = zone_specifier.matches self.assertEqual(2, len(matches)) self.assertEqual(DateTuple(2010, 12, 1, 0, 'w'), matches[0].startDateTime) self.assertEqual(DateTuple(2011, 3, 27, 2 * 3600, 's'), matches[0].untilDateTime) self.assertEqual('Russia', matches[0].zoneEra.policyName) self.assertEqual(DateTuple(2011, 3, 27, 2 * 3600, 's'), matches[1].startDateTime) self.assertEqual(DateTuple(2012, 2, 1, 0, 'w'), matches[1].untilDateTime) self.assertEqual('-', matches[1].zoneEra.policyName) transitions = zone_specifier.transitions self.assertEqual(2, len(transitions)) self.assertEqual(DateTuple(2010, 12, 1, 0, 'w'), transitions[0].startDateTime) self.assertEqual(DateTuple(2011, 3, 27, 2 * 3600, 'w'), transitions[0].untilDateTime) self.assertEqual(3 * 3600, transitions[0].offsetSeconds) self.assertEqual(0 * 3600, transitions[0].deltaSeconds) self.assertEqual(DateTuple(2011, 3, 27, 3 * 3600, 'w'), transitions[1].startDateTime) self.assertEqual(DateTuple(2012, 2, 1, 0 * 3600, 'w'), transitions[1].untilDateTime) self.assertEqual(4 * 3600, transitions[1].offsetSeconds) self.assertEqual(0 * 3600, transitions[1].deltaSeconds)
def _validate_test_data_for_zone(self, zone_name, items): zone_info = self.zone_infos[zone_name] zone_specifier = ZoneSpecifier( zone_info_data=zone_info, viewing_months=self.viewing_months, debug=self.debug_specifier, in_place_transitions=self.in_place_transitions, optimize_candidates=self.optimize_candidates) for item in items: if self.year and self.year != item.y: continue # Print out diagnostics if mismatch detected or if debug flag given unix_seconds = item.epoch + SECONDS_SINCE_UNIX_EPOCH ldt = datetime.utcfromtimestamp(unix_seconds) header = ( "======== Testing %s; at %sw; utc %s; epoch %s; unix %s" % (zone_name, _test_item_to_string(item), ldt, item.epoch, unix_seconds)) if self.debug_specifier: logging.info(header) try: info = zone_specifier.get_timezone_info_for_seconds(item.epoch) except Exception: logging.exception('Exception with test data %s', item) raise is_matched = info.total_offset == item.total_offset status = '**Matched**' if is_matched else '**Mismatched**' body = ('%s: AceTime(%s); Expected(%s)' % (status, to_utc_string(info.utc_offset, info.dst_offset), to_utc_string(item.total_offset - item.dst_offset, item.dst_offset))) if is_matched: if self.debug_specifier: logging.info(body) zone_specifier.print_matches_and_transitions() else: if not self.debug_specifier: logging.error(header) logging.error(body) zone_specifier.print_matches_and_transitions()