From 1ed1d60d2388b64ae21ffb827586248f4bd5fb8e Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Thu, 4 Oct 2018 22:28:42 +1300 Subject: [PATCH] Issue #80: invert order of checks when time ticks --- isodatetime/data.py | 90 ++++++++++++++++++++++---------------------- isodatetime/tests.py | 26 +++++++++++++ 2 files changed, 71 insertions(+), 45 deletions(-) diff --git a/isodatetime/data.py b/isodatetime/data.py index dc3e853..fcc0ad3 100644 --- a/isodatetime/data.py +++ b/isodatetime/data.py @@ -1162,62 +1162,62 @@ def add_truncated(self, year_of_century=None, year_of_decade=None, minute_of_hour=None, second_of_minute=None): """Combine this TimePoint with truncated time properties.""" new = self.copy() - if hour_of_day is not None and minute_of_hour is None: - minute_of_hour = 0 - if ((hour_of_day is not None or minute_of_hour is not None) and - second_of_minute is None): - second_of_minute = 0 - if second_of_minute is not None or minute_of_hour is not None: - new.to_hour_minute_second() - if second_of_minute is not None: - while new.second_of_minute != second_of_minute: - new.second_of_minute += 1.0 - new.tick_over() - if minute_of_hour is not None: - while new.minute_of_hour != minute_of_hour: - new.minute_of_hour += 1.0 - new.tick_over() - if hour_of_day is not None: - while new.hour_of_day != hour_of_day: - new.hour_of_day += 1.0 + if year_of_century is not None: + new.to_calendar_date() + new_year_of_century = new.year % 100 + while new_year_of_century != year_of_century: + new.year += 1 + new_year_of_century = new.year % 100 + if year_of_decade is not None: + new.to_calendar_date() + new_year_of_decade = new.year % 10 + while new_year_of_decade != year_of_decade: + new.year += 1 + new_year_of_decade = new.year % 10 + if month_of_year is not None: + new.to_calendar_date() + while new.month_of_year != month_of_year: + new.month_of_year += 1 new.tick_over() - if day_of_week is not None: + if week_of_year is not None: new.to_week_date() - while new.day_of_week != day_of_week: - new.day_of_week += 1 - new.tick_over() - if day_of_month is not None: - new.to_calendar_date() - while new.day_of_month != day_of_month: - new.day_of_month += 1 + while new.week_of_year != week_of_year: + new.week_of_year += 1 new.tick_over() if day_of_year is not None: new.to_ordinal_date() while new.day_of_year != day_of_year: new.day_of_year += 1 new.tick_over() - if week_of_year is not None: + if day_of_month is not None: + new.to_calendar_date() + while new.day_of_month != day_of_month: + new.day_of_month += 1 + new.tick_over() + if day_of_week is not None: new.to_week_date() - while new.week_of_year != week_of_year: - new.week_of_year += 1 + while new.day_of_week != day_of_week: + new.day_of_week += 1 new.tick_over() - if month_of_year is not None: - new.to_calendar_date() - while new.month_of_year != month_of_year: - new.month_of_year += 1 + if hour_of_day is not None: + while new.hour_of_day != hour_of_day: + new.hour_of_day += 1.0 new.tick_over() - if year_of_decade is not None: - new.to_calendar_date() - new_year_of_decade = new.year % 10 - while new_year_of_decade != year_of_decade: - new.year += 1 - new_year_of_decade = new.year % 10 - if year_of_century is not None: - new.to_calendar_date() - new_year_of_century = new.year % 100 - while new_year_of_century != year_of_century: - new.year += 1 - new_year_of_century = new.year % 100 + if minute_of_hour is not None: + while new.minute_of_hour != minute_of_hour: + new.minute_of_hour += 1.0 + new.tick_over() + if second_of_minute is not None: + while new.second_of_minute != second_of_minute: + new.second_of_minute += 1.0 + new.tick_over() + if second_of_minute is not None or minute_of_hour is not None: + new.to_hour_minute_second() + if ((hour_of_day is not None or minute_of_hour is not None) and + second_of_minute is None): + second_of_minute = 0 + if hour_of_day is not None and minute_of_hour is None: + minute_of_hour = 0 return new def __add__(self, other, no_copy=False): diff --git a/isodatetime/tests.py b/isodatetime/tests.py index ab965cf..54f9329 100644 --- a/isodatetime/tests.py +++ b/isodatetime/tests.py @@ -1204,6 +1204,32 @@ def test_timepoint_time_zone(self): duration, data.Duration(days=0), i_test_date_str + " - " + j_test_date_str) + def test_timepoint_adding_truncated_timepoint(self): + """See issue #80. When adding a truncated time, the result timepoint + must not be inconsistent, e.g. + + 2000-01-01T00:00:00Z + 03-30T00:00:00Z = 2000-03-02T00:00:00Z + + bug: was 2000-03-01T00:00:00Z, but expected 2000-03-30T00:00:00Z + """ + t1 = data.TimePoint(year=2000, month_of_year=1, day_of_month=1, + hour_of_day=0, minute_of_hour=0, + second_of_minute=0, time_zone_hour=0, + time_zone_minute=0) + t2 = data.TimePoint(month_of_year=3, day_of_month=30, + hour_of_day=0, minute_of_hour=0, + second_of_minute=0, time_zone_hour=0, + time_zone_minute=0, truncated=True) + t3 = t1 + t2 + self.assertEqual(2000, t3.year) + self.assertEqual(3, t3.month_of_year) + self.assertEqual(30, t3.day_of_month) + self.assertEqual(0, t3.hour_of_day) + self.assertEqual(0, t3.minute_of_hour) + self.assertEqual(0, t3.second_of_minute) + self.assertEqual(data.Duration(hours=0, minutes=0), t3.get_time_zone()) + self.assertEqual("2000-03-30T00:00:00Z", str(t3)) + def test_timepoint_dumper(self): """Test the dumping of TimePoint instances.""" parser = parsers.TimePointParser(allow_truncated=True,