[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')