[Python-checkins] python/nondist/sandbox/datetime datetime.c,1.22,1.23 datetime.h,1.9,1.10 datetime.py,1.63,1.64
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Thu, 21 Nov 2002 19:34:44 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv26013
Modified Files:
datetime.c datetime.h datetime.py
Log Message:
Copied over many comments from the .py version -- much of this code is
incomprehensible without them. Fixed some typos and misdeclarations.
Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** datetime.c 22 Nov 2002 02:59:56 -0000 1.22
--- datetime.c 22 Nov 2002 03:34:42 -0000 1.23
***************
*** 17,24 ****
{
PyObject_HEAD
! int hashcode;
! long int days;
! long int seconds;
! long int microseconds;
} PyDateTime_Delta;
--- 17,24 ----
{
PyObject_HEAD
! long hashcode;
! long days;
! long seconds;
! long microseconds;
} PyDateTime_Delta;
***************
*** 64,67 ****
--- 64,82 ----
*/
+ /* For each month ordinal in 1..12, the number of days in that month,
+ * and the number of days before that month in the same year. These
+ * are correct for non-leap years only.
+ */
+ static int _days_in_month[] = {
+ 0, /* unused; this vector uses 1-based indexing */
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+
+ static int _days_before_month[] = {
+ 0, /* unused; this vector uses 1-based indexing */
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+ };
+
+ /* year -> 1 if leap year, else 0. */
static int
is_leap(int year)
***************
*** 76,87 ****
}
static int
days_in_month(int year, int month)
{
- static int _days_in_month[] = {
- 0, /* unused; this vector uses 1-based indexing */
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
-
assert(month >= 1);
assert(month <= 12);
--- 91,98 ----
}
+ /* month, year -> number of days in that month in that year */
static int
days_in_month(int year, int month)
{
assert(month >= 1);
assert(month <= 12);
***************
*** 92,114 ****
}
! static long
! days_before_year(int year)
! {
! int y = year - 1;
! /* XXX This is incorrect if year <= 0; we really want the floor
! * XXX here.
! * XXX If we're sticking to strictly positive years, it would be
! * XXX better to change all these signatures to use unsigned ints.
! */
! return y*365 + y/4 - y/100 + y/400;
! }
!
! /* Each entry at index 1..12 gives the number of days before each
! * month on non-leap years.
! */
! static int _days_before_month[] = {
! 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
! };
!
static int
days_before_month(int year, int month)
--- 103,107 ----
}
! /* month, year -> number of days in year preceeding first day of month */
static int
days_before_month(int year, int month)
***************
*** 124,127 ****
--- 117,137 ----
}
+ /* year -> number of days before January 1st of year. Remember that we
+ * start with year 1, so days_before_year(1) == 0.
+ */
+ static long
+ days_before_year(int year)
+ {
+ int y = year - 1;
+ /* XXX This is incorrect if year <= 0; we really want the floor
+ * XXX here.
+ * XXX If we're sticking to strictly positive years, it would be
+ * XXX better to change all these signatures to use unsigned ints.
+ */
+ assert(year > 0);
+ return y*365 + y/4 - y/100 + y/400;
+ }
+
+
/* Number of days in 4, 100, and 400 year cycles. That these have
* the correct values is asserted in the module init function.
***************
*** 133,140 ****
/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
static void
! ord_to_ymd(long ordinal, long *year, long *month, long *day)
{
int n, n1, n4, n100, n400, leapyear, preceding;
assert(ordinal >= 1);
--ordinal;
--- 143,172 ----
/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
static void
! ord_to_ymd(long ordinal, long *year, long *month, long *day)
{
int n, n1, n4, n100, n400, leapyear, preceding;
+ /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
+ * leap years repeats exactly every 400 years. The basic strategy is
+ * to find the closest 400-year boundary at or before ordinal, then
+ * work with the offset from that boundary to ordinal. Life is much
+ * clearer if we subtract 1 from ordinal first -- then the values
+ * of ordinal at 400-year boundaries are exactly those divisible
+ * by DI400Y:
+ *
+ * D M Y n n-1
+ * -- --- ---- ---------- ----------------
+ * 31 Dec -400 -DI400Y -DI400Y -1
+ * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
+ * ...
+ * 30 Dec 000 -1 -2
+ * 31 Dec 000 0 -1
+ * 1 Jan 001 1 0 400-year boundary
+ * 2 Jan 001 2 1
+ * 3 Jan 001 3 2
+ * ...
+ * 31 Dec 400 DI400Y DI400Y -1
+ * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
+ */
assert(ordinal >= 1);
--ordinal;
***************
*** 143,152 ****
--- 175,196 ----
*year = n400 * 400 + 1;
+ /* Now n is the (non-negative) offset, in days, from January 1 of
+ * year, to the desired date. Now compute how many 100-year cycles
+ * precede n.
+ * Note that it's possible for n100 to equal 4! In that case 4 full
+ * 100-year cycles precede the desired day, which implies the
+ * desired day is December 31 at the end of a 400-year cycle.
+ */
n100 = n / DI100Y;
n = n % DI100Y;
+ /* Now compute how many 4-year cycles precede it. */
n4 = n / DI4Y;
n = n % DI4Y;
+ /* And now how many single years. Again n1 can be 4, and again
+ * meaning that the desired day is December 31 at the end of the
+ * 4-year cycle.
+ */
n1 = n / 365;
n = n % 365;
***************
*** 160,163 ****
--- 204,212 ----
return;
}
+
+ /* Now the year is correct, and n is the offset from January 1. We
+ * find the month via an estimate that's either exact or one too
+ * large.
+ */
leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
assert(leapyear == is_leap(*year));
***************
*** 183,186 ****
--- 232,236 ----
}
+ /* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
static int
weekday(int year, int month, int day)
Index: datetime.h
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** datetime.h 21 Nov 2002 22:55:26 -0000 1.9
--- datetime.h 22 Nov 2002 03:34:42 -0000 1.10
***************
*** 5,9 ****
--- 5,27 ----
#define DATETIME_H
+ /* Fields are packed into successive bytes, each viewed as unsigned and
+ * big-endian, unless otherwise noted:
+ *
+ * byte offset
+ * 0 year 2 bytes, 1-9999
+ * 2 month 1 byte, 1-12
+ * 3 day 1 byte, 1-31
+ * 4 hour 1 byte, 0-23
+ * 5 minute 1 byte, 0-59
+ * 6 second 1 byte, 0-59
+ * 7 usecond 3 bytes, 0-999999
+ * 10 tzoffset 2 bytes, signed, in minutes, -1439 .. 1439
+ * 12
+ */
+
+ /* # of bytes for year, month, and day. */
#define _PyDateTime_DATE_DATA_SIZE 4
+
+ /* # of bytes for year, month, day, hour, minute, second, and usecond. */
#define _PyDateTime_DATETIME_DATA_SIZE 10
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.63
retrieving revision 1.64
diff -C2 -d -r1.63 -r1.64
*** datetime.py 20 Nov 2002 03:23:34 -0000 1.63
--- datetime.py 22 Nov 2002 03:34:42 -0000 1.64
***************
*** 655,659 ****
The first ISO week of the year is the (Mon-Sun) week
! containing the year's first Thursday; everything rest derives
from that.
--- 655,659 ----
The first ISO week of the year is the (Mon-Sun) week
! containing the year's first Thursday; everything else derives
from that.