mirror of https://github.com/python/cpython
bpo-30155: Add macros to get tzinfo from datetime instances (GH-21633)
Add PyDateTime_DATE_GET_TZINFO() and PyDateTime_TIME_GET_TZINFO() macros.
This commit is contained in:
parent
9c4eac7f02
commit
2e4dd336e5
|
@ -185,6 +185,11 @@ must not be ``NULL``, and the type is not checked:
|
||||||
|
|
||||||
Return the microsecond, as an int from 0 through 999999.
|
Return the microsecond, as an int from 0 through 999999.
|
||||||
|
|
||||||
|
.. c:function:: PyObject* PyDateTime_DATE_GET_TZINFO(PyDateTime_DateTime *o)
|
||||||
|
|
||||||
|
Return the tzinfo (which may be ``None``).
|
||||||
|
|
||||||
|
.. versionadded:: 3.10
|
||||||
|
|
||||||
Macros to extract fields from time objects. The argument must be an instance of
|
Macros to extract fields from time objects. The argument must be an instance of
|
||||||
:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``,
|
:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``,
|
||||||
|
@ -209,6 +214,12 @@ and the type is not checked:
|
||||||
|
|
||||||
Return the microsecond, as an int from 0 through 999999.
|
Return the microsecond, as an int from 0 through 999999.
|
||||||
|
|
||||||
|
.. c:function:: PyObject* PyDateTime_TIME_GET_TZINFO(PyDateTime_Time *o)
|
||||||
|
|
||||||
|
Return the tzinfo (which may be ``None``).
|
||||||
|
|
||||||
|
.. versionadded:: 3.10
|
||||||
|
|
||||||
|
|
||||||
Macros to extract fields from time delta objects. The argument must be an
|
Macros to extract fields from time delta objects. The argument must be an
|
||||||
instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must
|
instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must
|
||||||
|
|
|
@ -231,6 +231,12 @@ New Features
|
||||||
Python executable.
|
Python executable.
|
||||||
(Contributed by Victor Stinner in :issue:`23427`.)
|
(Contributed by Victor Stinner in :issue:`23427`.)
|
||||||
|
|
||||||
|
* The :c:func:`PyDateTime_DATE_GET_TZINFO` and
|
||||||
|
:c:func:`PyDateTime_TIME_GET_TZINFO` macros have been added for accessing
|
||||||
|
the ``tzinfo`` attributes of :class:`datetime.datetime` and
|
||||||
|
:class:`datetime.time` objects.
|
||||||
|
(Contributed by Zackery Spytz in :issue:`30155`.)
|
||||||
|
|
||||||
Porting to Python 3.10
|
Porting to Python 3.10
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,10 @@ typedef struct
|
||||||
|
|
||||||
|
|
||||||
/* Apply for date and datetime instances. */
|
/* Apply for date and datetime instances. */
|
||||||
|
|
||||||
|
// o is a pointer to a time or a datetime object.
|
||||||
|
#define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo)
|
||||||
|
|
||||||
#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
|
#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
|
||||||
((PyDateTime_Date*)o)->data[1])
|
((PyDateTime_Date*)o)->data[1])
|
||||||
#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2])
|
#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2])
|
||||||
|
@ -128,6 +132,8 @@ typedef struct
|
||||||
(((PyDateTime_DateTime*)o)->data[8] << 8) | \
|
(((PyDateTime_DateTime*)o)->data[8] << 8) | \
|
||||||
((PyDateTime_DateTime*)o)->data[9])
|
((PyDateTime_DateTime*)o)->data[9])
|
||||||
#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold)
|
#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold)
|
||||||
|
#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \
|
||||||
|
((PyDateTime_DateTime *)(o))->tzinfo : Py_None)
|
||||||
|
|
||||||
/* Apply for time instances. */
|
/* Apply for time instances. */
|
||||||
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
|
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
|
||||||
|
@ -138,6 +144,8 @@ typedef struct
|
||||||
(((PyDateTime_Time*)o)->data[4] << 8) | \
|
(((PyDateTime_Time*)o)->data[4] << 8) | \
|
||||||
((PyDateTime_Time*)o)->data[5])
|
((PyDateTime_Time*)o)->data[5])
|
||||||
#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold)
|
#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold)
|
||||||
|
#define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \
|
||||||
|
((PyDateTime_Time *)(o))->tzinfo : Py_None)
|
||||||
|
|
||||||
/* Apply for time delta instances */
|
/* Apply for time delta instances */
|
||||||
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
|
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
|
||||||
|
|
|
@ -5991,30 +5991,36 @@ class CapiTest(unittest.TestCase):
|
||||||
|
|
||||||
for klass in [datetime, DateTimeSubclass]:
|
for klass in [datetime, DateTimeSubclass]:
|
||||||
for args in [(1993, 8, 26, 22, 12, 55, 99999),
|
for args in [(1993, 8, 26, 22, 12, 55, 99999),
|
||||||
(1993, 8, 26, 22, 12, 55, 99999)]:
|
(1993, 8, 26, 22, 12, 55, 99999,
|
||||||
|
timezone.utc)]:
|
||||||
d = klass(*args)
|
d = klass(*args)
|
||||||
with self.subTest(cls=klass, date=args):
|
with self.subTest(cls=klass, date=args):
|
||||||
hour, minute, second, microsecond = _testcapi.PyDateTime_DATE_GET(d)
|
hour, minute, second, microsecond, tzinfo = \
|
||||||
|
_testcapi.PyDateTime_DATE_GET(d)
|
||||||
|
|
||||||
self.assertEqual(hour, d.hour)
|
self.assertEqual(hour, d.hour)
|
||||||
self.assertEqual(minute, d.minute)
|
self.assertEqual(minute, d.minute)
|
||||||
self.assertEqual(second, d.second)
|
self.assertEqual(second, d.second)
|
||||||
self.assertEqual(microsecond, d.microsecond)
|
self.assertEqual(microsecond, d.microsecond)
|
||||||
|
self.assertIs(tzinfo, d.tzinfo)
|
||||||
|
|
||||||
def test_PyDateTime_TIME_GET(self):
|
def test_PyDateTime_TIME_GET(self):
|
||||||
class TimeSubclass(time):
|
class TimeSubclass(time):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for klass in [time, TimeSubclass]:
|
for klass in [time, TimeSubclass]:
|
||||||
for args in [(12, 30, 20, 10), (12, 30, 20, 10)]:
|
for args in [(12, 30, 20, 10),
|
||||||
|
(12, 30, 20, 10, timezone.utc)]:
|
||||||
d = klass(*args)
|
d = klass(*args)
|
||||||
with self.subTest(cls=klass, date=args):
|
with self.subTest(cls=klass, date=args):
|
||||||
hour, minute, second, microsecond = _testcapi.PyDateTime_TIME_GET(d)
|
hour, minute, second, microsecond, tzinfo = \
|
||||||
|
_testcapi.PyDateTime_TIME_GET(d)
|
||||||
|
|
||||||
self.assertEqual(hour, d.hour)
|
self.assertEqual(hour, d.hour)
|
||||||
self.assertEqual(minute, d.minute)
|
self.assertEqual(minute, d.minute)
|
||||||
self.assertEqual(second, d.second)
|
self.assertEqual(second, d.second)
|
||||||
self.assertEqual(microsecond, d.microsecond)
|
self.assertEqual(microsecond, d.microsecond)
|
||||||
|
self.assertIs(tzinfo, d.tzinfo)
|
||||||
|
|
||||||
def test_timezones_offset_zero(self):
|
def test_timezones_offset_zero(self):
|
||||||
utc0, utc1, non_utc = _testcapi.get_timezones_offset_zero()
|
utc0, utc1, non_utc = _testcapi.get_timezones_offset_zero()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Add :c:func:`PyDateTime_DATE_GET_TZINFO` and
|
||||||
|
:c:func:`PyDateTime_TIME_GET_TZINFO` macros for accessing the ``tzinfo``
|
||||||
|
attributes of :class:`datetime.datetime` and :class:`datetime.time` objects.
|
|
@ -115,14 +115,9 @@ class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCa
|
||||||
#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
|
#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
|
||||||
#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
|
#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
|
||||||
|
|
||||||
/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
|
#define HASTZINFO _PyDateTime_HAS_TZINFO
|
||||||
* p->hastzinfo.
|
#define GET_TIME_TZINFO PyDateTime_TIME_GET_TZINFO
|
||||||
*/
|
#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO
|
||||||
#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
|
|
||||||
#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
|
|
||||||
((PyDateTime_Time *)(p))->tzinfo : Py_None)
|
|
||||||
#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
|
|
||||||
((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
|
|
||||||
/* M is a char or int claiming to be a valid month. The macro is equivalent
|
/* M is a char or int claiming to be a valid month. The macro is equivalent
|
||||||
* to the two-sided Python test
|
* to the two-sided Python test
|
||||||
* 1 <= M <= 12
|
* 1 <= M <= 12
|
||||||
|
|
|
@ -2677,8 +2677,9 @@ test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj)
|
||||||
minute = PyDateTime_DATE_GET_MINUTE(obj);
|
minute = PyDateTime_DATE_GET_MINUTE(obj);
|
||||||
second = PyDateTime_DATE_GET_SECOND(obj);
|
second = PyDateTime_DATE_GET_SECOND(obj);
|
||||||
microsecond = PyDateTime_DATE_GET_MICROSECOND(obj);
|
microsecond = PyDateTime_DATE_GET_MICROSECOND(obj);
|
||||||
|
PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj);
|
||||||
|
|
||||||
return Py_BuildValue("(llll)", hour, minute, second, microsecond);
|
return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2690,8 +2691,9 @@ test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj)
|
||||||
minute = PyDateTime_TIME_GET_MINUTE(obj);
|
minute = PyDateTime_TIME_GET_MINUTE(obj);
|
||||||
second = PyDateTime_TIME_GET_SECOND(obj);
|
second = PyDateTime_TIME_GET_SECOND(obj);
|
||||||
microsecond = PyDateTime_TIME_GET_MICROSECOND(obj);
|
microsecond = PyDateTime_TIME_GET_MICROSECOND(obj);
|
||||||
|
PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj);
|
||||||
|
|
||||||
return Py_BuildValue("(llll)", hour, minute, second, microsecond);
|
return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -484,9 +484,7 @@ zoneinfo_tzname(PyObject *self, PyObject *dt)
|
||||||
return tti->tzname;
|
return tti->tzname;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
|
#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO
|
||||||
#define GET_DT_TZINFO(p) \
|
|
||||||
(HASTZINFO(p) ? ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zoneinfo_fromutc(PyObject *obj_self, PyObject *dt)
|
zoneinfo_fromutc(PyObject *obj_self, PyObject *dt)
|
||||||
|
|
Loading…
Reference in New Issue