[Python-checkins] python/nondist/sandbox/datetime doc.txt,1.3,1.4 obj_date.c,1.20,1.21 test_both.py,1.32,1.33

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Wed, 04 Dec 2002 14:07:24 -0800


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

Modified Files:
	doc.txt obj_date.c test_both.py 
Log Message:
Implemented the date fromtimestamp() and fromordinal() class methods (the
Python implementation already had them).
Added a simple test for extreme ordinal values.


Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** doc.txt	4 Dec 2002 19:49:11 -0000	1.3
--- doc.txt	4 Dec 2002 22:07:15 -0000	1.4
***************
*** 150,153 ****
--- 150,174 ----
      If an argument outside those ranges is given, ValueError is raised.
  
+ Other constructors (class methods):
+ 
+   - today()
+ 
+     Return the current local date.  This is equivalent to
+     fromtimestamp(time.time()).
+ 
+   - fromtimestamp(timestamp)
+ 
+     Return the local date corresponding to the POSIX timestamp, such as
+     is returned by time.time().  This may raise ValueError, if the
+     timestamp is out of the range of values supported by the platform C
+     localtime() function.  It's common for this to be restricted to
+     years in 1970 through 2038.
+ 
+   - fromordinal(ordinal)
+ 
+     Return the date corresponding to the proleptic Gregorian ordinal,
+     where January 1 of year 1 has ordinal 1.  ValueError is raised
+     unless 1 <= ordinal <= date.max.toordinal().  For any date d,
+     date.fromordinal(d.toordinal()) == d
  
  Class attributes:

Index: obj_date.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_date.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** obj_date.c	4 Dec 2002 05:08:14 -0000	1.20
--- obj_date.c	4 Dec 2002 22:07:15 -0000	1.21
***************
*** 156,159 ****
--- 156,161 ----
  }
  
+ /* Constructor. */
+ 
  static PyObject *
  date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
***************
*** 188,191 ****
--- 190,268 ----
  }
  
+ /* Class-method constructors. */
+ 
+ /* Return new date from localtime(t). */
+ static PyObject *
+ date_local_from_time_t(PyObject *cls, time_t t)
+ {
+ 	struct tm *tm;
+ 	PyObject *result = NULL;
+ 
+ 	tm = localtime(&t);
+ 	if (tm)
+ 		result = PyObject_CallFunction(cls, "iii",
+ 					       tm->tm_year + 1900,
+ 					       tm->tm_mon + 1,
+ 					       tm->tm_mday);
+ 	else
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"timestamp out of range for "
+ 				"platform localtime() function");
+ 	return result;
+ }
+ 
+ /* Return new date from current time. */
+ static PyObject *
+ date_today(PyObject *self, PyObject *cls)
+ {
+ 	time_t timet;
+ 
+ 	time(&timet);
+ 	return date_local_from_time_t(cls, timet);
+ }
+ 
+ /* Return new date from given timestamp (Python timestamp -- a double). */
+ static PyObject *
+ date_fromtimestamp(PyObject *self, PyObject *args)
+ {
+ 	PyObject *cls;
+ 	double timestamp;
+ 	PyObject *result = NULL;
+ 
+ 	if (PyArg_ParseTuple(args, "Od:fromtimestamp", &cls, &timestamp))
+ 		result = date_local_from_time_t(cls, (time_t)timestamp);
+ 	return result;
+ }
+ 
+ /* Return new date from proleptic Gregorian ordinal.  Raises ValueError if
+  * the ordinal is out of range.
+  */
+ static PyObject *
+ date_fromordinal(PyObject *self, PyObject *args)
+ {
+ 	PyObject *result = NULL;
+ 	PyObject *cls;
+ 	long ordinal;
+ 
+ 
+ 	if (PyArg_ParseTuple(args, "Ol:fromtimestamp", &cls, &ordinal)) {
+ 		long year;
+ 		long month;
+ 		long day;
+ 
+ 		if (ordinal < 1)
+ 			PyErr_SetString(PyExc_ValueError, "ordinal must be "
+ 							  ">= 1");
+ 		else {
+ 			ord_to_ymd(ordinal, &year, &month, &day);
+ 			result = PyObject_CallFunction(cls, "lll",
+ 						       year, month, day);
+ 		}
+ 	}
+ 	return result;
+ }
+ 
+ /* Attributes. */
+ 
  static PyObject *
  date_year(PyDateTime_Date *self, void *unused)
***************
*** 351,369 ****
  
  static PyObject *
- date_today(PyObject *self, PyObject *cls)
- {
- 	/* XXX need to create the instance by calling cls(y,mon,d,h,min,s,u) */
- 	struct tm *tm;
- 	time_t timet;
- 
- 	time(&timet);
- 	tm = localtime(&timet);
- 
- 	return PyObject_CallFunction(cls, "iii",
- 				     tm->tm_year + 1900, tm->tm_mon + 1,
- 				     tm->tm_mday);
- }
- 
- static PyObject *
  date_toordinal(PyDateTime_Date *self)
  {
--- 428,431 ----
***************
*** 436,441 ****
  static PyMethodDef date_methods[] = {
  	/* Class methods: */
! 	{"today",         (PyCFunction)date_today,       METH_O | METH_CLASS,
! 	 "Return a new date that represents the current date."},
  
  	/* Instance methods: */
--- 498,509 ----
  static PyMethodDef date_methods[] = {
  	/* Class methods: */
! 	{"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
! 							   METH_CLASS,
! 	 "timestamp -> local date from a POSIX timestamp (like time.time())."},
! 	{"fromordinal", (PyCFunction)date_fromordinal,	METH_VARARGS |
! 							METH_CLASS,
! 	 "int -> date corresponding to a proleptic Gregorian ordinal."},
! 	{"today",         (PyCFunction)date_today,	METH_O | METH_CLASS,
! 	 "Construct local date corresponing to current day."},
  
  	/* Instance methods: */

Index: test_both.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_both.py,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** test_both.py	4 Dec 2002 19:24:32 -0000	1.32
--- test_both.py	4 Dec 2002 22:07:16 -0000	1.33
***************
*** 351,354 ****
--- 351,379 ----
                      n += 1
  
+     def test_extreme_ordinals(self):
+         a = self.theclass.min
+         a = self.theclass(a.year, a.month, a.day)  # get rid of time parts
+         aord = a.toordinal()
+         b = a.fromordinal(aord)
+         self.assertEqual(a, b)
+ 
+         self.assertRaises(ValueError, lambda: a.fromordinal(aord - 1))
+ 
+         b = a + timedelta(days=1)
+         self.assertEqual(b.toordinal(), aord + 1)
+         self.assertEqual(b, self.theclass.fromordinal(aord + 1))
+ 
+         a = self.theclass.max
+         a = self.theclass(a.year, a.month, a.day)  # get rid of time parts
+         aord = a.toordinal()
+         b = a.fromordinal(aord)
+         self.assertEqual(a, b)
+ 
+         self.assertRaises(ValueError, lambda: a.fromordinal(aord + 1))
+ 
+         b = a - timedelta(days=1)
+         self.assertEqual(b.toordinal(), aord - 1)
+         self.assertEqual(b, self.theclass.fromordinal(aord - 1))
+ 
      def test_bad_constructor_arguments(self):
          # bad years