def test_fixed_timezone(): tz = fixed_timezone(19800) tz2 = fixed_timezone(18000) dt = datetime(2016, 11, 26, tzinfo=tz) assert 18000 == tz2.utcoffset(dt).total_seconds() assert tz2.dst(dt) == timedelta()
def test_fixed_timezone(): tz = fixed_timezone(19800) tz2 = fixed_timezone(18000) dt = datetime(2016, 11, 26, tzinfo=tz) assert 18000 == tz2.utcoffset(dt).total_seconds() assert tz2.dst(dt) == timedelta()
def time_period( dt_string, *, in_=False, on=False, before=False, after=False ): match = DATETIME_RE.match(dt_string) if not match or match['year'] is None: raise argparse.ArgumentTypeError(f"'{dt_string}' is not a supported datetime string.") parsed = ParsedDateTime(**match.groupdict()) if parsed.tz_hour: tz_offset = 0 if parsed.tz_hour is not None: tz_offset += parsed.tz_hour * 3600 if parsed.tz_minute is not None: tz_offset += parsed.tz_minute * 60 if parsed.tz_oper == '-': tz_offset *= -1 parsed_tz = fixed_timezone(tz_offset) else: parsed_tz = pendulum.local_timezone() if in_: if parsed.day: raise argparse.ArgumentTypeError( f"Datetime string must contain only year or year/month for 'in' option." ) start = pendulum.datetime( parsed.year, parsed.month or 1, parsed.day or 1, tz=parsed_tz ) if parsed.month: end = start.end_of('month') else: end = start.end_of('year') return pendulum.period( start, end ) elif on: if ( not all( getattr(parsed, attr) for attr in ['year', 'month', 'day'] ) or parsed.hour ): raise argparse.ArgumentTypeError( f"Datetime string must contain only year, month, and day for 'on' option." ) dt = pendulum.datetime( parsed.year, parsed.month, parsed.day, tz=parsed_tz ) return pendulum.period( dt.start_of('day'), dt.end_of('day') ) elif before: start = DateTime.min dt = pendulum.datetime( parsed.year, parsed.month or 1, parsed.day or 1, parsed.hour or 23, parsed.minute or 59, parsed.second or 59, 0, tz=parsed_tz ) if not parsed.month: dt = dt.start_of('year') elif not parsed.day: dt = dt.start_of('month') elif not parsed.hour: dt = dt.start_of('day') elif not parsed.minute: dt = dt.start_of('hour') elif not parsed.second: dt = dt.start_of('minute') return pendulum.period( start, dt ) elif after: end = DateTime.max dt = pendulum.datetime( parsed.year, parsed.month or 1, parsed.day or 1, parsed.hour or 23, parsed.minute or 59, parsed.second or 59, 99999, tz=parsed_tz ) if not parsed.month: dt = dt.end_of('year') elif not parsed.day: dt = dt.end_of('month') elif not parsed.hour: dt = dt.start_of('day') elif not parsed.minute: dt = dt.start_of('hour') elif not parsed.second: dt = dt.start_of('minute') return pendulum.period( dt, end )
('2019', period(DateTime.min, datetime(2019, 1, 1, tz='local'))), ('2019-08', period(DateTime.min, datetime(2019, 8, 1, tz='local'))), ('201908', period(DateTime.min, datetime(2019, 8, 1, tz='local'))), ('2019-08-22', period(DateTime.min, datetime(2019, 8, 22, tz='local'))), ('20190822', period(DateTime.min, datetime(2019, 8, 22, tz='local'))), ('2019-08-22T16', period(DateTime.min, datetime(2019, 8, 22, 16, tz='local'))), ('2019-08-22T16:00', period(DateTime.min, datetime(2019, 8, 22, 16, tz='local'))), ('2019-08-22T16:00:00', period(DateTime.min, datetime(2019, 8, 22, 16, tz='local'))), ('2019-08-22 16:00:00', period(DateTime.min, datetime(2019, 8, 22, 16, tz='local'))), ('2019-08-22T16:00:00 04', period(DateTime.min, datetime(2019, 8, 22, 16, tz=fixed_timezone(4 * 3600)))), ('2019-08-22T16:00:00+04', period(DateTime.min, datetime(2019, 8, 22, 16, tz=fixed_timezone(4 * 3600)))), ('2019-08-22T16:00:00-04', period(DateTime.min, datetime(2019, 8, 22, 16, tz=fixed_timezone(-4 * 3600)))), ('2019-08-22T16:00:00 04:00', period(DateTime.min, datetime(2019, 8, 22, 16, tz=fixed_timezone(4 * 3600)))), ('2019-08-22T16:00:00+04:00', period(DateTime.min, datetime(2019, 8, 22, 16, tz=fixed_timezone(4 * 3600)))), ('2019-08-22T16:00:00-04:00', period(DateTime.min, datetime(2019, 8, 22, 16, tz=fixed_timezone(-4 * 3600)))),
def datetime_string_to_time_period(dt_string, *, in_=False, on=False, before=False, after=False): if not any([in_, on, before, after]): raise ValueError("One of in_, on, before, or after must be ``True``.") if dt_string == 'today': dt_string = pendulum.today().to_date_string() elif dt_string == 'yesterday': dt_string = pendulum.yesterday().to_date_string() elif dt_string == 'now': # pragma: nocover dt_string = pendulum.now().end_of('minute').to_datetime_string() match = DATETIME_RE.match(dt_string) if (not match or match['year'] is None): raise ValueError(f"'{dt_string}' is not a supported datetime string.") parsed = ParsedDateTime(**match.groupdict()) if parsed.tz_hour: tz_offset = 0 if parsed.tz_hour is not None: # pragma: nobranch tz_offset += parsed.tz_hour * 3600 if parsed.tz_minute is not None: # pragma: nobranch tz_offset += parsed.tz_minute * 60 if parsed.tz_oper == '-': # pragma: nobranch tz_offset *= -1 parsed_tz = fixed_timezone(tz_offset) else: parsed_tz = pendulum.local_timezone() if in_: if parsed.day: raise ValueError( f"Datetime string must contain only year or year/month for 'in' option." ) start = pendulum.datetime(parsed.year, parsed.month or 1, parsed.day or 1, tz=parsed_tz) if parsed.month: end = start.end_of('month') else: end = start.end_of('year') period = pendulum.period(start, end) elif on: if (not all( getattr(parsed, attr) for attr in ['year', 'month', 'day']) or parsed.hour): raise ValueError( f"Datetime string must contain only year, month, and day for 'on' option." ) dt = pendulum.datetime(parsed.year, parsed.month, parsed.day, tz=parsed_tz) period = pendulum.period(dt.start_of('day'), dt.end_of('day')) elif before: start = DateTime.min dt = pendulum.datetime( parsed.year, parsed.month if parsed.month is not None else 1, parsed.day if parsed.day is not None else 1, parsed.hour if parsed.hour is not None else 23, parsed.minute if parsed.minute is not None else 59, parsed.second if parsed.second is not None else 59, 0, tz=parsed_tz) if parsed.month is None: dt = dt.start_of('year') elif parsed.day is None: dt = dt.start_of('month') elif parsed.hour is None: dt = dt.start_of('day') elif parsed.minute is None: dt = dt.start_of('hour') elif parsed.second is None: dt = dt.start_of('minute') period = pendulum.period(start, dt) else: end = DateTime.max dt = pendulum.datetime( parsed.year, parsed.month if parsed.month is not None else 1, parsed.day if parsed.day is not None else 1, parsed.hour if parsed.hour is not None else 23, parsed.minute if parsed.minute is not None else 59, parsed.second if parsed.second is not None else 59, 0, tz=parsed_tz) if parsed.month is None: dt = dt.end_of('year') elif parsed.day is None: dt = dt.end_of('month') elif parsed.hour is None: dt = dt.end_of('day') elif parsed.minute is None: dt = dt.start_of('hour') elif parsed.second is None: dt = dt.start_of('minute') period = pendulum.period(dt, end) return period