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.
This commit is contained in:
parent
79d9bfa28f
commit
14adbe77b5
|
@ -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
|
# If we know the week of the year and what day of that week, we can figure
|
||||||
# out the Julian day of the year
|
# out the Julian day of the year
|
||||||
# Calculations below assume 0 is a Monday
|
# Calculations below assume 0 is a Monday
|
||||||
if julian == -1 and week_of_year != -1 and weekday != -1 and year != -1:
|
if julian == -1 and week_of_year != -1 and weekday != -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
|
|
||||||
# Calculate how many days in week 0
|
# Calculate how many days in week 0
|
||||||
first_weekday = datetime_date(year, 1, 1).weekday()
|
first_weekday = datetime_date(year, 1, 1).weekday()
|
||||||
preceeding_days = 7 - first_weekday
|
preceeding_days = 7 - first_weekday
|
||||||
if preceeding_days == 7:
|
if preceeding_days == 7:
|
||||||
preceeding_days = 0
|
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
|
# 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,
|
# 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
|
# adding in days in week 0, and the number of days from Monday to the
|
||||||
# day of the week
|
# day of the week
|
||||||
if not week_of_year:
|
if week_of_year == 0:
|
||||||
julian = 1 + weekday - first_weekday
|
julian = 1 + weekday - first_weekday
|
||||||
else:
|
else:
|
||||||
days_to_week = preceeding_days + (7 * (week_of_year - 1))
|
days_to_week = preceeding_days + (7 * (week_of_year - 1))
|
||||||
|
|
|
@ -424,20 +424,35 @@ class CalculationTests(unittest.TestCase):
|
||||||
def test_helper(ymd_tuple, test_reason):
|
def test_helper(ymd_tuple, test_reason):
|
||||||
for directive in ('W', 'U'):
|
for directive in ('W', 'U'):
|
||||||
format_string = "%%Y %%%s %%w" % directive
|
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)
|
strp_output = _strptime.strptime(strp_input, format_string)
|
||||||
self.failUnless(strp_output[:3] == ymd_tuple,
|
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,
|
(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, 3), "week 0")
|
||||||
test_helper((1901, 1, 8), "common case")
|
test_helper((1901, 1, 8), "common case")
|
||||||
test_helper((1901, 1, 13), "day on Sunday")
|
test_helper((1901, 1, 13), "day on Sunday")
|
||||||
test_helper((1901, 1, 14), "day on Monday")
|
test_helper((1901, 1, 14), "day on Monday")
|
||||||
test_helper((1905, 1, 1), "Jan 1 on Sunday")
|
test_helper((1905, 1, 1), "Jan 1 on Sunday")
|
||||||
test_helper((1906, 1, 1), "Jan 1 on Monday")
|
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((1905, 12, 31), "Dec 31 on Sunday")
|
||||||
test_helper((1906, 12, 31), "Dec 31 on Monday")
|
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):
|
class CacheTests(unittest.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue