diff options
Diffstat (limited to 'Modules/_datetimemodule.c')
-rw-r--r-- | Modules/_datetimemodule.c | 80 |
1 files changed, 16 insertions, 64 deletions
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 1d583a5..5289222 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -3287,6 +3287,11 @@ timezone_str(PyDateTime_TimeZone *self) Py_INCREF(self->name); return self->name; } + if ((PyObject *)self == PyDateTime_TimeZone_UTC || + (GET_TD_DAYS(self->offset) == 0 && + GET_TD_SECONDS(self->offset) == 0 && + GET_TD_MICROSECONDS(self->offset) == 0)) + return PyUnicode_FromString("UTC"); /* Offset is normalized, so it is negative if days < 0 */ if (GET_TD_DAYS(self->offset) < 0) { sign = '-'; @@ -4083,44 +4088,6 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, tzinfo); } -static time_t -_PyTime_DoubleToTimet(double x) -{ - time_t result; - double diff; - - result = (time_t)x; - /* How much info did we lose? time_t may be an integral or - * floating type, and we don't know which. If it's integral, - * we don't know whether C truncates, rounds, returns the floor, - * etc. If we lost a second or more, the C rounding is - * unreasonable, or the input just doesn't fit in a time_t; - * call it an error regardless. Note that the original cast to - * time_t can cause a C error too, but nothing we can do to - * worm around that. - */ - diff = x - (double)result; - if (diff <= -1.0 || diff >= 1.0) { - PyErr_SetString(PyExc_OverflowError, - "timestamp out of range for platform time_t"); - result = (time_t)-1; - } - return result; -} - -/* Round a double to the nearest long. |x| must be small enough to fit - * in a C long; this is not checked. - */ -static double -_PyTime_RoundHalfEven(double x) -{ - double rounded = round(x); - if (fabs(x-rounded) == 0.5) - /* halfway case: round to even */ - rounded = 2.0*round(x/2.0); - return rounded; -} - /* Internal helper. * Build datetime from a Python timestamp. Pass localtime or gmtime for f, * to control the interpretation of the timestamp. Since a double doesn't @@ -4129,32 +4096,17 @@ _PyTime_RoundHalfEven(double x) * to get that much precision (e.g., C time() isn't good enough). */ static PyObject * -datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp, +datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, PyObject *tzinfo) { time_t timet; - double fraction; - int us; + long us; - timet = _PyTime_DoubleToTimet(timestamp); - if (timet == (time_t)-1 && PyErr_Occurred()) + if (_PyTime_ObjectToTimeval(timestamp, + &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1) return NULL; - fraction = timestamp - (double)timet; - us = (int)_PyTime_RoundHalfEven(fraction * 1e6); - if (us < 0) { - /* Truncation towards zero is not what we wanted - for negative numbers (Python's mod semantics) */ - timet -= 1; - us += 1000000; - } - /* If timestamp is less than one microsecond smaller than a - * full second, round up. Otherwise, ValueErrors are raised - * for some floats. */ - if (us == 1000000) { - timet += 1; - us = 0; - } - return datetime_from_timet_and_us(cls, f, timet, us, tzinfo); + + return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); } /* Internal helper. @@ -4227,11 +4179,11 @@ static PyObject * datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) { PyObject *self; - double timestamp; + PyObject *timestamp; PyObject *tzinfo = Py_None; static char *keywords[] = {"timestamp", "tz", NULL}; - if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp", + if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp", keywords, ×tamp, &tzinfo)) return NULL; if (check_tzinfo_subclass(tzinfo) < 0) @@ -4255,10 +4207,10 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) static PyObject * datetime_utcfromtimestamp(PyObject *cls, PyObject *args) { - double timestamp; + PyObject *timestamp; PyObject *result = NULL; - if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp)) + if (PyArg_ParseTuple(args, "O:utcfromtimestamp", ×tamp)) result = datetime_from_timestamp(cls, gmtime, timestamp, Py_None); return result; @@ -4761,7 +4713,7 @@ local_timezone(PyDateTime_DateTime *utc_time) if (seconds == NULL) goto error; Py_DECREF(delta); - timestamp = PyLong_AsLong(seconds); + timestamp = _PyLong_AsTime_t(seconds); Py_DECREF(seconds); if (timestamp == -1 && PyErr_Occurred()) return NULL; |