Пример #1
0
    def _validate_test_data_for_zone(
        self,
        zone_name: str,
        items: List[TestItem],
    ) -> int:
        """Compare the given test 'items' generatd by TestDataGenerator (using
        pytz) with the expected datetime components from ZoneSpecifier. Returns
        the number of errors.
        """
        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)

        num_errors = 0
        for item in items:
            if self.year is not None 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 = (f'======== Testing {zone_name}; '
                      f'at {_test_item_to_string(item)}w; '
                      f'utc {ldt}; '
                      f'epoch {item.epoch}; '
                      f'unix {unix_seconds}')

            if self.debug_specifier:
                logging.info(header)

            info = zone_specifier.get_timezone_info_for_seconds(item.epoch)
            if not info:
                logging.info("timezone info not found")
                continue

            is_matched = info.total_offset == item.total_offset
            status = '**Matched**' if is_matched else '**Mismatched**'
            ace_time_string = to_utc_string(info.utc_offset, info.dst_offset)
            utc_string = to_utc_string(item.total_offset - item.dst_offset,
                                       item.dst_offset)
            body = (f'{status}: '
                    f'AceTime({ace_time_string}); '
                    f'Expected({utc_string})')
            if is_matched:
                if self.debug_specifier:
                    logging.info(body)
                    zone_specifier.print_matches_and_transitions()
            else:
                num_errors += 1
                if not self.debug_specifier:
                    logging.error(header)
                logging.error(body)
                zone_specifier.print_matches_and_transitions()

        return num_errors
Пример #2
0
def main() -> None:
    # Configure command line flags.
    parser = argparse.ArgumentParser(description='Zone Agent.')
    parser.add_argument(
        '--viewing_months',
        help='Number of months to use for calculations (12, 13, 14, 36)',
        type=int,
        default=14)
    parser.add_argument('--transition',
                        help='Print the transition instead of timezone info',
                        action='store_true')
    parser.add_argument('--debug',
                        help='Print debugging info',
                        action='store_true')
    parser.add_argument(
        '--in_place_transitions',
        help='Use in-place Transition array to determine Active Transitions',
        action="store_true",
        default=True)
    parser.add_argument('--no_in_place_transitions',
                        help='Disable --in_place_transitions',
                        action="store_false",
                        dest='in_place_transitions')
    parser.add_argument('--optimize_candidates',
                        help='Optimize the candidate transitions',
                        action='store_true',
                        default=True)
    parser.add_argument('--no_optimize_candidates',
                        help='Disable --optimize_candidates',
                        action='store_false',
                        dest='optimize_candidates')
    parser.add_argument('--zone', help='Name of time zone', required=True)
    parser.add_argument('--year', help='Year of interest', type=int)
    parser.add_argument('--date', help='DateTime of interest')
    args = parser.parse_args()

    # Configure logging
    logging.basicConfig(level=logging.INFO)

    # Find the zone.
    zone_info = cast(ZoneInfo, zone_infos.ZONE_INFO_MAP.get(args.zone))
    if not zone_info:
        logging.error("Zone '%s' not found", args.zone)
        sys.exit(1)

    # Create the ZoneSpecifier for zone
    zone_specifier = ZoneSpecifier(
        zone_info_data=zone_info,
        viewing_months=args.viewing_months,
        debug=args.debug,
        in_place_transitions=args.in_place_transitions,
        optimize_candidates=args.optimize_candidates)

    if args.year:
        zone_specifier.init_for_year(args.year)
        if args.debug:
            logging.info('==== Final matches and transitions')
        zone_specifier.print_matches_and_transitions()
    elif args.date:
        dt: datetime = datetime.strptime(args.date, "%Y-%m-%dT%H:%M")
        if args.transition:
            transition = zone_specifier.get_transition_for_datetime(dt)
            if transition:
                logging.info(transition)
            else:
                logging.error('Transition not found')
        else:
            offset_info = zone_specifier.get_timezone_info_for_datetime(dt)
            if not offset_info:
                logging.info('Invalid time')
            else:
                logging.info(
                    '%s (%s)',
                    to_utc_string(
                        offset_info.utc_offset,
                        offset_info.dst_offset,
                    ),
                    offset_info.abbrev,
                )
    else:
        print("One of --year or --date must be provided")
        sys.exit(1)