Skip to content Skip to sidebar Skip to footer

How Can I Check If The Current Locale Uses Am/pm Or 24-hour Time?

I'm trying to update a string which should display the time differently depending on whether the current locale uses AM/PM or 24-hours If the locale can be determined I can then up

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 the strftime/strptime docs is rendered with a 24 hour clock (%X produces 21:30:00 under en_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:

  1. Having the default locale unset is the same as having it set to 'C'.
  2. 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?"