changeset 241:be0a3606471f

Again, properly implement week-in-year (#46).
author cmlenz
date Tue, 07 Aug 2007 17:17:28 +0000
parents e37046445638
children 9b13c9a436c5
files babel/dates.py babel/tests/dates.py
diffstat 2 files changed, 42 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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)
Copyright (C) 2012-2017 Edgewall Software