After changing the locale in a Python program, what is the safe way to change it back to its original value?
What I have tried so far is to store the original locale as returned by locale.getlocale
before making changes and then using locale.setlocale
afterwards to change back to it.
Example program:
import datetime
import locale
now = datetime.datetime.now()
locale.setlocale(locale.LC_ALL, '')
print("Date using your locale : %s" % now.strftime('%c'))
saved = locale.getlocale(locale.LC_TIME)
locale.setlocale(locale.LC_TIME, 'C')
print("Date using the C locale : %s" % now.strftime('%c'))
locale.setlocale(locale.LC_TIME, saved)
print("Date using your locale again: %s" % now.strftime('%c'))
However, this does not always work as expected. It seems that the problem arises with locales that have a modifier (the bit after the '@' sign). Trying the following with Python 3.7 on a Debian 10 system illustrates the problem:
$ LC_TIME=sr_RS.utf8@latin python3 example.py
Date using your locale : četvrtak, 01. avgust 2019. 14:43:43
Date using the C locale : Thu Aug 1 14:43:43 2019
Date using your locale again: четвртак, 01. август 2019. 14:43:43
So it appears to change back to the sr_RS.utf8
locale instead of the original sr_RS.utf8@latin
locale, forgetting about the @latin
modifier.
Furthermore, if the corresponding locale without the modifier is not available, there will be an error when trying to switch back. For example on a system where the nan_TW.utf8@latin
locale is present, but nan_TW.utf8
is not:
$ LC_TIME=nan_TW.utf8@latin python3 example.py
Date using your locale : 2019 8g 01 (p4) 14:44:29
Date using the C locale : Thu Aug 1 14:44:29 2019
Traceback (most recent call last):
File "example.py", line 13, in <module>
locale.setlocale(locale.LC_TIME, saved)
File "/usr/local/lib/python3.7/locale.py", line 604, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting
Is there a safe way to switch back to the original locale setting? Something that could be used for example in a library routine intended to be used within a larger locale-aware program to temporarily switch the locale (for example, for formatting dates in another locale) and then switching it back, without permanently interfering with the locale of the calling program.
In the manual is written: For 8-bit strings, this method is locale-dependent. How is this method locale-depedent? In what locales are there digits that are outside the 0-9 range? Also, if this is locale dependent, does python have a method for checking it with a specific locale (i.e. only 0-9 digits).
Is there a safe way to switch back to the original locale setting? (if it uses modifiers as e.g.
latin
)
No, not with standard function calls: locale.getlocale()
ignores all modifiers except euro
, see source.
A workaround is to use the internal function _setlocale
, i.e. reverse engineer getlocale
without the _parse_localename
part:
import datetime
import locale
now = datetime.datetime.now()
locale.setlocale(locale.LC_ALL, '')
print("Date using your locale : %s" % now.strftime('%c'))
saved = locale._setlocale(locale.LC_TIME)
locale.setlocale(locale.LC_TIME, 'C')
print("Date using the C locale : %s" % now.strftime('%c'))
locale.setlocale(locale.LC_TIME, saved)
print("Date using your locale again: %s" % now.strftime('%c'))
Example:
$ LC_TIME=sr_RS.utf8@latin python3 so57312038.py
Date using your locale : sreda, 21. avgust 2019. 00:00:29
Date using the C locale : Wed Aug 21 00:00:29 2019
Date using your locale again: sreda, 21. avgust 2019. 00:00:29
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With