diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 2598ab40b23da7..691a1e127ad2b3 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2476,6 +2476,11 @@ where historical changes have been made to civil time. Return ``dt + offset``. The *dt* argument must be an aware :class:`.datetime` instance, with ``tzinfo`` set to ``self``. +.. attribute:: timezone.name + + The *name* passed to the constructor, or ``None`` if no name was passed. + + .. versionadded:: next Class attributes: diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index f8fb9bf4d47e7b..5e1821dbc8d2cd 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -392,6 +392,10 @@ datetime :meth:`datetime.time.strptime`. (Contributed by Stan Ulbrych and Karoline Pauls in :gh:`157290`.) +* Add :attr:`datetime.timezone.name`, the *name* passed to the constructor, + or ``None`` if no name was passed. + (Contributed by Stan Ulbrych in :gh:`131210`.) + dbm.gnu ------- diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py index f5ac965d3cfedf..076183139b28ae 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -2539,6 +2539,11 @@ def tzname(self, dt): raise TypeError("tzname() argument must be a datetime instance" " or None") + @property + def name(self): + """Name given when the timezone was created.""" + return self._name + def dst(self, dt): if isinstance(dt, datetime) or dt is None: return None diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index d3c67761b6a109..53285d918c17ca 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -354,6 +354,17 @@ def test_tzname(self): with self.assertRaises(TypeError): self.EST.tzname('') with self.assertRaises(TypeError): self.EST.tzname(5) + def test_name(self): + for offset, name in ((5 * HOUR, 'IST'), (ZERO, '\ud800')): + with self.subTest(offset=offset, name=name): + self.assertEqual(name, timezone(offset, name).name) + + for tz in (UTC, timezone(ZERO), timezone(-5 * HOUR)): + with self.subTest(tz=tz): + self.assertIsNone(tz.name) + + with self.assertRaises(AttributeError): self.EST.name = 'EST' + def test_fromutc(self): with self.assertRaises(ValueError): timezone.utc.fromutc(self.DT) diff --git a/Misc/NEWS.d/next/Library/2025-03-13-20-21-00.gh-issue-115810.qwrb231.rst b/Misc/NEWS.d/next/Library/2025-03-13-20-21-00.gh-issue-115810.qwrb231.rst new file mode 100644 index 00000000000000..253f4a5de95738 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-03-13-20-21-00.gh-issue-115810.qwrb231.rst @@ -0,0 +1,2 @@ +Add :attr:`datetime.timezone.name`, the *name* passed to the constructor, +or ``None`` if no name was passed. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 71057ad704d012..959abcf5e421cf 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -4558,6 +4558,22 @@ static PyMethodDef timezone_methods[] = { {NULL, NULL} }; +static PyObject * +timezone_name(PyObject *op, void *Py_UNUSED(closure)) +{ + PyDateTime_TimeZone *self = PyTimeZone_CAST(op); + if (self->name == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(self->name); +} + +static PyGetSetDef timezone_getset[] = { + {"name", timezone_name, NULL, + PyDoc_STR("Name given when the timezone was created.")}, + {NULL} +}; + static PyTypeObject PyDateTime_TimeZoneType = { PyVarObject_HEAD_INIT(NULL, 0) "datetime.timezone", /* tp_name */ @@ -4588,7 +4604,7 @@ static PyTypeObject PyDateTime_TimeZoneType = { 0, /* tp_iternext */ timezone_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + timezone_getset, /* tp_getset */ &PyDateTime_TZInfoType, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */