diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py index fcf4416f331092..3141c8766d3004 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -2115,7 +2115,13 @@ def astimezone(self, tz=None): utc = (self - myoffset).replace(tzinfo=tz) # Convert from UTC to tz's local time. - return tz.fromutc(utc) + result = tz.fromutc(utc) + + # Set fold if there is discrepancy between timestamp and timezone. + if tz.utcoffset(result) != myoffset: + result = result.replace(fold=1) + + return result # Ways to produce a string. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 07d7089be09d20..072f0dbd63c11f 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -6754,6 +6754,29 @@ datetime_astimezone(PyObject *op, PyObject *args, PyObject *kw) PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), temp); Py_DECREF(temp); + /* Set fold if there is discrepancy between timestamp and timezone. */ + if (result != NULL) { + offset = call_utcoffset(tzinfo, (PyObject *)result); + if (offset == NULL || offset == Py_None || !PyDelta_Check(offset)) { + Py_XDECREF(offset); + goto naive; + } + + PyObject *myoffset = call_utcoffset(tzinfo, (PyObject *)self); + if (myoffset == NULL || myoffset == Py_None || !PyDelta_Check(myoffset)) { + Py_XDECREF(offset); + Py_XDECREF(myoffset); + return NULL; + } + + if (delta_cmp(offset, myoffset) == 0) { + DATE_SET_FOLD(result, 1); + } + + Py_XDECREF(myoffset); + Py_XDECREF(offset); + } + return (PyObject *)result; }