[Python-checkins] CVS: python/nondist/sandbox/datetime datetime.py,1.16,1.17 test_datetime.py,1.11,1.12

Guido van Rossum gvanrossum@users.sourceforge.net
Sat, 02 Mar 2002 18:50:54 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory usw-pr-cvs1:/tmp/cvs-serv31633

Modified Files:
	datetime.py test_datetime.py 
Log Message:
Add weekday() and iso_calendar() methods.


Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** datetime.py	3 Mar 2002 02:10:24 -0000	1.16
--- datetime.py	3 Mar 2002 02:50:52 -0000	1.17
***************
*** 545,548 ****
--- 545,594 ----
          return NotImplemented
  
+     # Day-of-the-week and week-of-the-year, according to ISO
+ 
+     def weekday(self):
+         "Return day of the week, where Monday == 0 (according to ISO)."
+         # The constant 6 was obtained experimentally :-)
+         return (_ymd2ord(self.__year, self.__month, self.__day) + 6) % 7
+ 
+     def isocalendar(self):
+         """Return a 3-tuple containing ISO year, week number, and weekday.
+ 
+         The first ISO week of the year is the (Mon-Sun) week
+         containing the year's first Thursday; everything rest derives
+         from that.
+ 
+         Note that the first week is 1, but Monday is 0.
+ 
+         ISO calendar algorithm taken from
+         http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
+         """
+         year = self.__year
+         week1monday = _isoweek1monday(year)
+         today = _ymd2ord(self.__year, self.__month, self.__day)
+         # Internally, week has origin 0
+         week, day = divmod(today - week1monday, 7)
+         if week < 0:
+             year -= 1
+             week1monday = _isoweek1monday(year)
+             week, day = divmod(today - week1monday, 7)
+         elif week >= 52:
+             if today >= _isoweek1monday(year+1):
+                 year += 1
+                 week = 0
+         return year, week+1, day
+ 
+ 
+ def _isoweek1monday(year):
+     # Helper to calculate the day number of the Monday starting week 1
+     # XXX This could be done more efficiently
+     THURSDAY = 3
+     firstday = _ymd2ord(year, 1, 1)
+     firstweekday = (firstday + 6) % 7 # See weekday() above
+     week1monday = firstday - firstweekday
+     if firstweekday > THURSDAY:
+         week1monday += 7
+     return week1monday
+ 
  
  def _test():

Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** test_datetime.py	3 Mar 2002 02:15:34 -0000	1.11
--- test_datetime.py	3 Mar 2002 02:50:52 -0000	1.12
***************
*** 194,197 ****
--- 194,261 ----
                           (((a - week) - day) - hour) - millisec)
  
+     def test_weekday(self):
+         for i in range(7):
+             # March 4, 2002 is a Monday
+             self.assertEqual(datetime(2002, 3, 4+i).weekday(), i)
+             # January 2, 1956 is a Monday
+             self.assertEqual(datetime(1956, 1, 2+i).weekday(), i)
+ 
+     def test_isocalendar(self):
+         # Check examples from
+         # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
+         for i in range(7):
+             d = datetime(2003, 12, 22+i)
+             self.assertEqual(d.isocalendar(), (2003, 52, i))
+             d = datetime(2003, 12, 29) + timedelta(i)
+             self.assertEqual(d.isocalendar(), (2004, 1, i))
+             d = datetime(2004, 1, 5+i)
+             self.assertEqual(d.isocalendar(), (2004, 2, i))
+             d = datetime(2009, 12, 21+i)
+             self.assertEqual(d.isocalendar(), (2009, 52, i))
+             d = datetime(2009, 12, 28) + timedelta(i)
+             self.assertEqual(d.isocalendar(), (2009, 53, i))
+             d = datetime(2010, 1, 4+i)
+             self.assertEqual(d.isocalendar(), (2010, 1, i))
+ 
+     def test_iso_long_years(self):
+         # Calculate long ISO years and compare to table from
+         # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
+         ISO_LONG_YEARS_TABLE = """
+               4   32   60   88 
+               9   37   65   93 
+              15   43   71   99 
+              20   48   76 
+              26   54   82
+ 
+             105  133  161  189 
+             111  139  167  195 
+             116  144  172 
+             122  150  178 
+             128  156  184
+ 
+             201  229  257  285 
+             207  235  263  291 
+             212  240  268  296 
+             218  246  274 
+             224  252  280
+ 
+             303  331  359  387 
+             308  336  364  392 
+             314  342  370  398 
+             320  348  376 
+             325  353  381
+         """
+         iso_long_years = map(int, ISO_LONG_YEARS_TABLE.split())
+         iso_long_years.sort()
+         L = []
+         for i in range(400):
+             d = datetime(2000+i, 12, 31)
+             d1 = datetime(1600+i, 12, 31)
+             self.assertEqual(d.isocalendar()[1:], d1.isocalendar()[1:])
+             if d.isocalendar()[1] == 53:
+                 L.append(i)
+         self.assertEqual(L, iso_long_years)
+ 
+ 
  def test_suite():
      s1 = unittest.makeSuite(TestDateTime, 'test')