From 14adbe77b5e9c68fb525d25961c86b5b0dbb1945 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 28 Oct 2004 04:49:21 +0000 Subject: Fix bug of implementation of algorithm for calculating the date from year, week of the year, and day of the week. Was not taking into consideration properly the issue of when %U is used for the week of the year but the year starts on Monday. Closes bug #1045381 again. --- Lib/_strptime.py | 22 ++++++++++++---------- Lib/test/test_strptime.py | 21 ++++++++++++++++++--- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 1a6e8a8..a6b54f3 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -391,25 +391,27 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): # If we know the week of the year and what day of that week, we can figure # out the Julian day of the year # Calculations below assume 0 is a Monday - if julian == -1 and week_of_year != -1 and weekday != -1 and year != -1: - # Adjust for U directive so that calculations are not dependent on - # directive used to figure out week of year - if weekday == 6 and week_of_year_start == 6: - week_of_year -= 1 - # For some reason when Dec 31 falls on a Monday the week of the year is - # off by a week; verified on both OS X and Solaris. - elif weekday == 0 and week_of_year_start == 6 and week_of_year >= 52: - week_of_year += 1 + if julian == -1 and week_of_year != -1 and weekday != -1: # Calculate how many days in week 0 first_weekday = datetime_date(year, 1, 1).weekday() preceeding_days = 7 - first_weekday if preceeding_days == 7: preceeding_days = 0 + # Adjust for U directive so that calculations are not dependent on + # directive used to figure out week of year + if weekday == 6 and week_of_year_start == 6: + week_of_year -= 1 + # If a year starts and ends on a Monday but a week is specified to + # start on a Sunday we need to up the week to counter-balance the fact + # that with %W that first Monday starts week 1 while with %U that is + # week 0 and thus shifts everything by a week + if weekday == 0 and first_weekday == 0 and week_of_year_start == 6: + week_of_year += 1 # If in week 0, then just figure out how many days from Jan 1 to day of # week specified, else calculate by multiplying week of year by 7, # adding in days in week 0, and the number of days from Monday to the # day of the week - if not week_of_year: + if week_of_year == 0: julian = 1 + weekday - first_weekday else: days_to_week = preceeding_days + (7 * (week_of_year - 1)) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index bc68851..785497a 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -424,20 +424,35 @@ class CalculationTests(unittest.TestCase): def test_helper(ymd_tuple, test_reason): for directive in ('W', 'U'): format_string = "%%Y %%%s %%w" % directive - strp_input = datetime_date(*ymd_tuple).strftime(format_string) + dt_date = datetime_date(*ymd_tuple) + strp_input = dt_date.strftime(format_string) strp_output = _strptime.strptime(strp_input, format_string) self.failUnless(strp_output[:3] == ymd_tuple, - "%s(%s) test failed w/ '%s': %s != %s" % + "%s(%s) test failed w/ '%s': %s != %s (%s != %s)" % (test_reason, directive, strp_input, - strp_output[:3], ymd_tuple[:3])) + strp_output[:3], ymd_tuple, + strp_output[7], dt_date.timetuple()[7])) test_helper((1901, 1, 3), "week 0") test_helper((1901, 1, 8), "common case") test_helper((1901, 1, 13), "day on Sunday") test_helper((1901, 1, 14), "day on Monday") test_helper((1905, 1, 1), "Jan 1 on Sunday") test_helper((1906, 1, 1), "Jan 1 on Monday") + test_helper((1906, 1, 7), "first Sunday in a year starting on Monday") test_helper((1905, 12, 31), "Dec 31 on Sunday") test_helper((1906, 12, 31), "Dec 31 on Monday") + test_helper((2008, 12, 29), "Monday in the last week of the year") + test_helper((2008, 12, 22), "Monday in the second-to-last week of the " + "year") + test_helper((1978, 10, 23), "randomly chosen date") + test_helper((2004, 12, 18), "randomly chosen date") + test_helper((1978, 10, 23), "year starting and ending on Monday while " + "date not on Sunday or Monday") + test_helper((1917, 12, 17), "year starting and ending on Monday with " + "a Monday not at the beginning or end " + "of the year") + test_helper((1917, 12, 31), "Dec 31 on Monday with year starting and " + "ending on Monday") class CacheTests(unittest.TestCase): -- cgit v0.12