You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
date.strftime and datetime.strftime format dates wrong in some locales. #130528
date.strftime and datetime.strftime format dates wrong in some locales. For example, when the locale is Bulgaria the '%A' format string returns an incorrect value.
>>>locale.setlocale(locale.LC_TIME, 'bg') # 'bg' is Bulgaria>>>date_str=datetime.date(2025, 2, 25).strftime('%A') # %A is locale's day of the week>>>date_str'âòîðíèê'>>>date_str.encode('cp1252').decode('cp1251') # I think we're interpreting a cp1251 string as cp1252'вторник'# Google tells me this is Tuesday in Bulgarian
This also fails with the '%x' format string
I've only tested this on Windows.
My guess is that CPython is making a narrow character API call and using the wrong code page. It should be using the wide character call instead.
Ok, second question. I think what's being returned with %A is encoded with something that is not necessarily useful for the LC_TIME language. CP-1252 is a legacy default format on Windows according to Wikipedia, and I assume that it's as if we had "no localized encoding".
@serhiy-storchaka you're more of an expert in this case, is it the expected behaviour? namely, should we expect the caller to actually perform the encode/decode themselves or is it something that's wrong with datetime?
Oh-oh, it is yet one issue similar to #69998 and bpo-28604. The workaround at he user side is to set LC_CTYPE to the same value as LC_TIME. We can fix this at Python side, but at the cost of making strftime() slower and potentially more thread-unsafe (it is already not thread-safe in sense that it can fail if the environment is changed in other thread, but now it will be able to break other threads by changing the environment).
I reproduce your case on Linux, so first of all, if you don't have locale (you can check it with locale -a command), you will get locale.Error: unsupported setting, but all available locales were utf8 so I think there was no error:
I got it. PC/pyconfig.h was removed in 79dad03 (gh-111650) and restored in 986c367 (gh-133779). Currently only 3.13 does not have it. HAVE_WCSFTIME is defined in PC/pyconfig.h, if it is not defined, strftime() is used instead of wcsftime(). I suspect it affects other code, we don't know how much.
I think this is a serious regression. PC/pyconfig.h should be restored in the 3.13 branch.
I think this is a serious regression. PC/pyconfig.h should be restored in the 3.13 branch.
In 3.13 it gets generated during build, in order to try and support free-threading. But that was a nightmare, so we rolled it back for 3.14 (so you can't just use Py_GIL_DISABLED when building an extension module - whoever is building has to provide it, potentially by checking sysconfig).
PC/pyconfig.h.in should be there, and it gets used with virtually no modification. Trust me when I say the entire build would be failing if it weren't there. As far as I'm aware, nobody has changed HAVE_WCFSTIME.
We can fix this at Python side, but at the cost of making strftime() slower and potentially more thread-unsafe (it is already not thread-safe in sense that it can fail if the environment is changed in other thread, but now it will be able to break other threads by changing the environment).
Perhaps the fix here is to use create_locale and strftime_l and explicitly pass the locale just to that call? No need to modify the global state if you're making the call directly.
Activity
picnixz commentedon Feb 25, 2025
picnixz commentedon Feb 25, 2025
Ok, second question. I think what's being returned with
%Ais encoded with something that is not necessarily useful for theLC_TIMElanguage. CP-1252 is a legacy default format on Windows according to Wikipedia, and I assume that it's as if we had "no localized encoding".@serhiy-storchaka you're more of an expert in this case, is it the expected behaviour? namely, should we expect the caller to actually perform the encode/decode themselves or is it something that's wrong with datetime?
tomasr8 commentedon Feb 25, 2025
I think
locale.getlocale(locale.LC_TIME)[1]should return the encoding used bystrftimeserhiy-storchaka commentedon Feb 25, 2025
Oh-oh, it is yet one issue similar to #69998 and bpo-28604. The workaround at he user side is to set LC_CTYPE to the same value as LC_TIME. We can fix this at Python side, but at the cost of making
strftime()slower and potentially more thread-unsafe (it is already not thread-safe in sense that it can fail if the environment is changed in other thread, but now it will be able to break other threads by changing the environment).donbarbos commentedon Feb 25, 2025
I reproduce your case on Linux, so first of all, if you don't have locale (you can check it with
locale -acommand), you will getlocale.Error: unsupported setting, but all available locales wereutf8so I think there was no error:(I checked the behavior on the
mainbranch and also version3.13)StanFromIreland commentedon Mar 21, 2025
Unable to reproduce on Linux, maybe this has something to do with how Windows is configured? That seems to be the case for other similar issues.
serhiy-storchaka commentedon Oct 17, 2025
I got it.
PC/pyconfig.hwas removed in 79dad03 (gh-111650) and restored in 986c367 (gh-133779). Currently only 3.13 does not have it.HAVE_WCSFTIMEis defined inPC/pyconfig.h, if it is not defined,strftime()is used instead ofwcsftime(). I suspect it affects other code, we don't know how much.I think this is a serious regression.
PC/pyconfig.hshould be restored in the 3.13 branch.cc @zooba, @Yhg1s
zooba commentedon Oct 20, 2025
In 3.13 it gets generated during build, in order to try and support free-threading. But that was a nightmare, so we rolled it back for 3.14 (so you can't just use
Py_GIL_DISABLEDwhen building an extension module - whoever is building has to provide it, potentially by checkingsysconfig).PC/pyconfig.h.inshould be there, and it gets used with virtually no modification. Trust me when I say the entire build would be failing if it weren't there. As far as I'm aware, nobody has changedHAVE_WCFSTIME.Perhaps the fix here is to use
create_localeandstrftime_land explicitly pass the locale just to that call? No need to modify the global state if you're making the call directly.serhiy-storchaka commentedon Oct 20, 2025
Ah, it turned out, there is other relavant difference between 3.13 and 3.14. The use of
wcsftime()on Windows was intentionally disabled in bpo-10653/gh-54862. It was enabled again in #125658. The original issue withwcsftime()was fixed in Windows 10 v2004 (build 19041).Since we don't support Windows older than Windows 10 v2004, perhaps #125658 can be backported. cc @Yhg1s