Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (revision 74106) +++ Lib/test/test_datetime.py (working copy) @@ -1120,6 +1120,12 @@ # blow up because other fields are insane. self.theclass(base[:2] + chr(ord_byte) + base[3:]) + def test_date_fromyday(self): + dt = date.fromyday(2009,200) + self.assertEqual(dt.day,19) + self.assertEqual(dt.month,7) + self.assertEqual(dt.year,2009) + ############################################################################# # datetime tests @@ -1667,6 +1673,10 @@ self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + dt1.second - 7) + def test_yday(self): + t = datetime.today() + self.assertEqual(t.yday(), t.timetuple()[7]) + class SubclassTime(time): sub_var = 1 Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (revision 74106) +++ Modules/datetimemodule.c (working copy) @@ -2263,16 +2263,48 @@ } return (PyObject *)me; } - if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, &year, &month, &day)) { if (check_date_args(year, month, day) < 0) return NULL; self = new_date_ex(year, month, day, type); } + + return self; } + +static char *dateyday_kws[] = {"year", "yday", NULL}; + +/* Returns new date from year and yday */ +static PyObject * +date_fromyday(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *self = NULL; + int year; + int month; + int day; + int yday; + + if(PyArg_ParseTupleAndKeywords(args, kw, "ii", dateyday_kws, + &year, &yday)) { + int days = 0; + for(month=1; month<=12; ++month) { + days += days_in_month(year,month); + if(yday < days) { + break; + } + } + day = abs(days_before_month(year,month) - yday); + if (check_date_args(year,month,day)) + return NULL; + self = new_date_ex(year, month, day, type); + } + return self; +} + + /* Return new date from localtime(t). */ static PyObject * date_local_from_time_t(PyObject *cls, double ts) @@ -2603,6 +2635,14 @@ } static PyObject * +date_yday(PyDateTime_Date *self) +{ + return PyInt_FromLong(days_before_month(GET_YEAR(self),GET_MONTH(self)) + + GET_DAY(self)); +} + + +static PyObject * date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw) { PyObject *clone; @@ -2688,6 +2728,10 @@ PyDoc_STR("Current date or datetime: same as " "self.__class__.fromtimestamp(time.time()).")}, + {"fromyday", (PyCFunction)date_fromyday, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("year, yday --> date from the year and yday")}, + /* Instance methods: */ {"ctime", (PyCFunction)date_ctime, METH_NOARGS, @@ -2702,6 +2746,9 @@ {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS, PyDoc_STR("Return time tuple, compatible with time.localtime().")}, + {"yday", (PyCFunction)date_yday, METH_NOARGS, + PyDoc_STR("Return the day of the year.")}, + {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS, PyDoc_STR("Return a 3-tuple containing ISO year, week number, and " "weekday.")},