How Can I Check If The Current Locale Uses Am/pm Or 24-hour Time?
Solution 1:
Using the time.strftime()
function with the %p
parameter will give the equivalent for AM/PM in the current locale, and for locales that don't use AM/PM an empty string is returned. I use this in the following way:
time_format_string = "%H:%M"# Ex: Swedenif time.strftime("%p"): # Checking if the string contains something
time_format_string = "%I:%M %p"# Ex: US
time_of_day_string = time.strftime(time_format_string)
print(time_of_day_string)
I've tried this for two locales (one with and another without AM/PM)
Reference: https://docs.python.org/3/library/time.html#time.strftime
Solution 2:
Tord, the behavior is odd, but this worked on Windows 7. Note that prior to setting the locale the time displayed as 24hour clock. Once locale was set it displayed using the 12hour AM/PM setting. That is the correct setting from my laptop.
Python 3.6.0 (v3.6.0:41df79263a11, Dec 232016, 08:06:12) [MSC v.190064 bit (AMD64)] on win32
Type"copyright", "credits"or"license()"for more information.
>>> import locale
>>> import time
>>> cur_locale = locale.getlocale() # current locale setting>>> cur_locale
('English_United States', '1252')
>>> time.strftime("%X") # %X - Locale’s appropriate time representation'20:01:47'>>> locale.setlocale(locale.LC_TIME, cur_locale)
'English_United States.1252'>>> time.strftime("%X") # %X - Locale’s appropriate time representation'8:02:11 PM'>>>
Solution 3:
Disclaimer 1: This was tested only on GNU/Linux with glibc. Your mileage may vary on Windows, macOS, Linux with non-GNU libc and on other operating systems.
Disclaimer 2: I tested this on Alpine Linux with musl libc and it does not work. You may encounter this when using Docker since Alpine is very popular for making minimalistic container images.
tl;dr
Use this:
import locale
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale(("LC_TIME",)))
The problem
This comment by @ShadowRanger drew my attention:
Given that the "locale appropriate time" for
en_US
in thestrftime
/strptime
docs is rendered with a 24 hour clock (%X
produces21:30:00
underen_US
locale), I doubt the Python locale information indicates whether the local standard is 12 or 24 hour clock. The U.S. is nearly 100% 12 hour clock, but the locale time representation is 24 hour.
Let's try to find out what's going on here.
A documentation for locale.getdefaultlocale() function gives us a hint:
According to POSIX, a program which has not called
setlocale(LC_ALL, '')
runs using the portable'C'
locale.
It looks like CPython uses the 'C'
locale by default, and its time representation seems to be 24-hour:
$ LC_TIME=C date
Tue Oct 27 13:06:54 UTC 2020
$ LC_TIME=en_US.UTF-8 date
Tue Oct 27 01:06:54 PM UTC 2020
$ TZ=UTC LC_TIME=de_DE.UTF-8 date
Di 27. Okt 13:06:54 UTC 2020
Let's confirm this:
$ LC_TIME=en_US.UTF-8 python3
>>> import locale
>>> import time
>>> locale.getlocale(locale.LC_TIME)
(None, None)
>>> time.strftime("%p")
'PM'>>> time.strftime("%X")
'13:03:34'>>> locale.setlocale(locale.LC_TIME, 'C')
'C'>>> locale.getlocale(locale.LC_TIME)
(None, None)
Here we can see two things:
- Having the default locale unset is the same as having it set to
'C'
. - Setting the
LC_TIME
environment variable without using it explicitly in Python does not give any effect.
I wonder why %p
is set if %X
does not use it? 🤔️
The solution
To make the program honour our locale preferences, we need to call locale.setlocale()
and supply it with LC_TIME
.
$ LC_TIME=en_US.UTF-8 python3
>>> import locale
>>> import time
>>> locale.setlocale(locale.LC_TIME, locale.getdefaultlocale(('LC_TIME',)))
'en_US.UTF-8'>>> time.strftime("%p")
'PM'>>> time.strftime("%X")
'01:03:59 PM'
$ LC_TIME=de_DE.UTF-8 python3
>>> import locale
>>> import time
>>> locale.setlocale(locale.LC_TIME, locale.getdefaultlocale(('LC_TIME',)))
'de_DE.UTF-8'>>> time.strftime("%p")
''>>> time.strftime("%X")
'13:06:13'
Post a Comment for "How Can I Check If The Current Locale Uses Am/pm Or 24-hour Time?"