# HG changeset patch # User cmlenz # Date 1186507048 0 # Node ID 4afe02d810834f2506f3387768112e61bda83bc4 # Parent 83ea377a1472b3577179dd7ceac8926810bbfabb Again, properly implement week-in-year (#46). diff --git a/babel/dates.py b/babel/dates.py --- a/babel/dates.py +++ b/babel/dates.py @@ -745,11 +745,12 @@ return get_month_names(width, context, self.locale)[self.value.month] def format_week(self, char, num): - # FIXME: this should really be based on the first_week_day and - # min_week_days locale data - if char.islower(): - return self.value.strftime('%W') - else: + if char.islower(): # week of year + return self.format(self.get_week_number(self.get_day_of_year()), + num) + else: # week of month + # FIXME: this should really be based on the first_week_day and + # min_week_days locale data return '%d' % ((self.value.day + 6 - self.value.weekday()) / 7 + 1) def format_weekday(self, char, num): @@ -764,8 +765,7 @@ return get_day_names(width, context, self.locale)[weekday] def format_day_of_year(self, num): - delta = self.value - date(self.value.year, 1, 1) - return self.format(delta.days + 1, num) + return self.format(self.get_day_of_year(), num) def format_period(self, char): period = {0: 'am', 1: 'pm'}[int(self.value.hour > 12)] @@ -798,6 +798,37 @@ def format(self, value, length): return ('%%0%dd' % length) % value + def get_day_of_year(self): + return (self.value - date(self.value.year, 1, 1)).days + 1 + + def get_week_number(self, day_of_period): + """Return the number of the week of a day within a period. This may be + the week number in a year or the week number in a month. + + Usually this will return a value equal to or greater than 1, but if the + first week of the period is so short that it actually counts as the last + week of the previous period, this function will return 0. + + >>> format = DateTimeFormat(date(2006, 1, 8), Locale.parse('de_DE')) + >>> format.get_week_number(6) + 1 + + >>> format = DateTimeFormat(date(2006, 1, 8), Locale.parse('en_US')) + >>> format.get_week_number(6) + 2 + + :param day_of_period: the number of the day in the period (usually + either the day of month or the day of year) + """ + first_day = (self.value.weekday() - self.locale.first_week_day - + day_of_period + 1) % 7 + if first_day < 0: + first_day += 7 + week_number = (day_of_period + first_day - 1) / 7 + if 7 - first_day >= self.locale.min_week_days: + week_number += 1 + return week_number + PATTERN_CHARS = { 'G': [1, 2, 3, 4, 5], # era diff --git a/babel/tests/dates.py b/babel/tests/dates.py --- a/babel/tests/dates.py +++ b/babel/tests/dates.py @@ -23,9 +23,11 @@ class DateTimeFormatTestCase(unittest.TestCase): def test_week_of_year(self): - d = date(2007, 4, 1) + d = date(2006, 1, 8) + fmt = dates.DateTimeFormat(d, locale='de_DE') + self.assertEqual('1', fmt['w']) fmt = dates.DateTimeFormat(d, locale='en_US') - self.assertEqual('13', fmt['w']) + self.assertEqual('02', fmt['ww']) def test_week_of_month(self): d = date(2007, 4, 1)