def _correct_progression(cls, last_time, curr_time, freq, missings, missing_value=None): # without a last_time the progression cannot be corrected if not last_time: return curr_time exp_time = increment_time(last_time, 1, freq) assert type(exp_time) == arrow.Arrow assert type(last_time) == arrow.Arrow or not last_time assert type(curr_time) == arrow.Arrow # everything is ok! if exp_time == curr_time: return curr_time # going back if curr_time < last_time: if cls._time_value_typo(curr_time, exp_time): return exp_time else: raise TimeValueGoingBackwards(curr_time, exp_time, last_time) # going forth with no missings allowed going_forth = curr_time > last_time if going_forth and not missings: if cls._time_value_typo(curr_time, exp_time): return exp_time else: raise TimeValueGoingForth(curr_time, exp_time, last_time) # going forth with implicit missings max_forth_time_value = increment_time(last_time, cls._max_forth_units(freq), freq) going_too_forth = curr_time > max_forth_time_value if going_too_forth and missings and missing_value == "Implicit": forth_time_value = cls._forth_time_value_typo( curr_time, max_forth_time_value) if forth_time_value: return forth_time_value else: return False # everything should be ok else: return curr_time
def _time_make_sense(self, params, time_value, last_time, next_time): """Check that a parsed time value make sense with the previous one. Args: params: Parameters of the time series. time_value: Recently parsed time value. last_time: Last time value that was parsed. next_time: Next value to be parsed into a time value. Returns: True or False, if the value make sense with the last one and the next one. """ # making sense with the last value if last_time: is_after_last = time_value > last_time max_forth_time_value = increment_time(last_time, self.MAX_IMPL, params["frequency"]) is_not_too_after_last = time_value <= max_forth_time_value else: is_after_last, is_not_too_after_last = True, True # making sense with the next value if next_time: try: next_time = self.parse_time(params, next_time, time_value) is_before_next = time_value < next_time max_forth_time_value = increment_time(time_value, self.MAX_IMPL, params["frequency"]) is_not_too_before_next = next_time <= max_forth_time_value except NoTimeValue: is_before_next, is_not_too_before_next = False, False else: is_before_next, is_not_too_before_next = True, True return (is_after_last and is_not_too_after_last and is_before_next and is_not_too_before_next)
def test_increment_time(self): time = arrow.get(2015, 12, 1) new_time = increment_time(time, 1, "S") exp_new_time = arrow.get(2015, 12, 1, 0, 0, 1) self.assertEqual(new_time, exp_new_time) new_time = increment_time(time, 1, "D") exp_new_time = arrow.get(2015, 12, 2) self.assertEqual(new_time, exp_new_time) new_time = increment_time(time, 1, "M") exp_new_time = arrow.get(2016, 1, 1) self.assertEqual(new_time, exp_new_time) new_time = increment_time(time, 1, "Q") exp_new_time = arrow.get(2016, 3, 1) self.assertEqual(new_time, exp_new_time) new_time = increment_time(time, 1, "A") exp_new_time = arrow.get(2016, 12, 1) self.assertEqual(new_time, exp_new_time)
def _fill_implicit_missings(cls, ws, values, frequency, time_header_coord, ini, end, alignment): """Fill time holes in the series with missing data.""" iter_ti = cls._time_index_iterator(ws, alignment, time_header_coord, ini, end) new_values = [] exp_time = None for obs_time, (i_value, value) in zip(iter_ti, enumerate(values)): obs_time = arrow.get(obs_time) exp_time = exp_time or obs_time # fill time holes in the series with missing data while exp_time < obs_time: new_values.append(np.nan) exp_time = increment_time(exp_time, 1, frequency) new_values.append(values[i_value]) exp_time = increment_time(exp_time, 1, frequency) return new_values
def test_increment_time_exception(self): with self.assertRaises(InvalidTimeFrequency): time = arrow.get(2015, 2, 15) increment_time(time, 4, "X")