def _parse_partial_datetime(dt_string): """Parse a partial date/time string. The string should be in an ISO 8601 format except that the date and time parts may be separated by a space or colon instead of T. :param dt_string: String to parse :return: list of datetime components :raise ValueError: if the string cannot be parsed as a date/time """ from cis.time_util import PartialDateTime # Separate date and time at first character that is one of 'T', ' ' or ':'. match = re.match(r'(?P<date>[^T :]+)(?:[T :])(?P<time>.+)$', dt_string) if match is not None: date_str = match.group('date') time_components = [int(x) for x in match.group('time').split(':')] else: date_str = dt_string time_components = [] date_components = [int(x) for x in date_str.split('-')] dt_components = list(date_components) if ((len(date_components) > 3) or (len(time_components) > 3) or (len(date_components) < 3) and (len(time_components) > 0)): raise ValueError() else: dt_components.extend(time_components) return PartialDateTime(*dt_components)
def test_can_subset_ungridded_data_by_partial_date_time(self): from cis.time_util import PartialDateTime data = cis.test.util.mock.make_dummy_ungridded_data_time_series(100) subset = data.subset(time=[PartialDateTime(1984, 9)]) assert (subset.data.tolist() == [ 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0 ])
def test_aggregating_over_time_with_partial_datetime(self): from cis.time_util import PartialDateTime, cis_standard_time_unit as tunit from datetime import datetime, timedelta data = make_regular_2d_with_time_ungridded_data() data.time.convert_to_std_time() output = data.aggregate( t=[PartialDateTime(1984, 9), timedelta(days=30)]) expected_t_bounds = [[ tunit.date2num(datetime(1984, 9, 1)), tunit.date2num(datetime(1984, 10, 1)) ]] assert_arrays_almost_equal(output[0].coord('time').bounds, expected_t_bounds) assert_arrays_almost_equal(output[0].data, [[[10.5]]])
def parse_datetime_can_parse_date_time_with_colon_separator(): dt = _parse_partial_datetime('2010-07-01:13:27:43') assert (dt == PartialDateTime(2010, 7, 1, 13, 27, 43))
def parse_datetime_can_parse_date_hour_min_sec_no_leading_zeros(): dt = _parse_partial_datetime('2010-3-4T5:6:7') assert (dt == PartialDateTime(2010, 3, 4, 5, 6, 7))
def parse_datetime_can_parse_date_hour_min_sec(): dt = _parse_partial_datetime('2010-07-01T13:27:43') assert (dt == PartialDateTime(2010, 7, 1, 13, 27, 43))
def parse_datetime_can_parse_date_hour(): dt = _parse_partial_datetime('2010-07-01T13') assert (dt == PartialDateTime(2010, 7, 1, 13))
def parse_datetime_can_parse_date(): dt = _parse_partial_datetime('2010-07-01') assert (dt == PartialDateTime(2010, 7, 1))
def parse_datetime_can_parse_year_month(): dt = _parse_partial_datetime('2010-07') print(dt) assert (dt == PartialDateTime(2010, 7))
def parse_datetime_can_parse_year(): dt = _parse_partial_datetime('2010') assert (dt == PartialDateTime(2010))
def test_convert_datetime_components_to_datetime_raises_error_if_invalid_time( self): start, end = PartialDateTime(2000, 6, 30, 12, 30, 60).range()
def test_convert_datetime_components_to_datetime_can_convert_date_hour_min_sec_as_lower_limit( self): start, end = PartialDateTime(1990, 6, 7, 12, 15, 45).range() assert (start == dt.datetime(1990, 6, 7, 12, 15, 45)) assert (end == dt.datetime(1990, 6, 7, 12, 15, 45))
def test_convert_datetime_components_to_datetime_can_convert_date_hour_as_lower_limit( self): start, end = PartialDateTime(1990, 6, 7, 18).range() assert (start == dt.datetime(1990, 6, 7, 18, 0, 0)) assert (end == dt.datetime(1990, 6, 7, 18, 59, 59))
def test_convert_datetime_components_to_datetime_can_convert_year_month_day_as_lower_limit( self): start, end = PartialDateTime(1990, 6, 7).range() assert (start == dt.datetime(1990, 6, 7, 0, 0, 0)) assert (end == dt.datetime(1990, 6, 7, 23, 59, 59))
def test_convert_datetime_components_to_datetime_can_convert_year_as_lower_limit( self): start, end = PartialDateTime(2000).range() assert (start == dt.datetime(2000, 1, 1, 0, 0, 0)) assert (end == dt.datetime(2000, 12, 31, 23, 59, 59))
def test_empty_step_raises_error_with_partial_datetime(self): from cis.time_util import PartialDateTime data = make_regular_2d_with_time_ungridded_data() data.time.convert_to_std_time() output = data.aggregate(t=[PartialDateTime(1984, 9), None])