I answered this question previously giving instructions for making modifications to the locale formats by compiling a modified version of the Qt Base libraries on Debian 10. This answer is similar, but has the specific commands I used when I did the same modifications on Debian 12. There are a few things that are a little different between the Debian 10 instructions and the Debian 12 instructions. The instructions are already complicated enough, so I thought it would be simpler to create a new answer than to try and modify the previous answer to cover both versions.
I also include (optional) instructions for modifying the glibc locales, separately, so as to give an answer as to how to modify date and time formats, for example, across KDE and all glibc applications.
I repeat a comment from my original answer: It is unfortunate that changing a date format or time format requires multiple hours to perform.
Instructions for Compiling QtBase with Changes to Locale Formats
Base system and assumptions:
- Installed Debian 12 with:
- desktop environment / KDE Plasma
- ssh server
- standard system utilities
- Assume that:
- the user can use sudo to run commands as root
- bash is the shell
- Make sure system is up-to-date and install necessary requirements for building source packages in Debian if not already installed.
sudo apt update
sudo apt upgrade
sudo apt install build-essential fakeroot devscripts
- Install other needed dependencies.
sudo apt build-dep qtbase-opensource-src
sudo apt install curl software-properties-common
- The QtBase source code that Debian 12 uses has python scripts that need to be run with Python2. (For some later version, the scripts were updated to use Python3.) This step installs Python2 on Debian 12. This might not be needed for other distributions. Debian 12 does not contain Python2 by default, so it is installed from Debian 9 (Stretch).
sudo add-apt-repository -S deb http://archive.debian.org/debian stretch main
sudo apt update
sudo apt install python2.7
sudo add-apt-repository -r deb http://archive.debian.org/debian stretch main
- Make a directory in which to work. I used,
QtLocaleFix in my home directory.
TOPDIR="${HOME}/QtLocaleFix"
mkdir -p "${TOPDIR}"
cd "${TOPDIR}"
- Create two subdirectories: one for the QtBase source code and one for the CLDR (Common Locale Data Repository).
QtBaseSrcDIR="${TOPDIR}/QtBaseSrc"
mkdir -p "${QtBaseSrcDIR}"
CLDRDIR="${TOPDIR}/CLDR"
mkdir -p "${CLDRDIR}"
- Get the source code for the QtBase libs (
libqt5core5a).
cd "${QtBaseSrcDIR}" && apt source qtbase-opensource-src
- The previous step downloaded source files for the QtBase libraries. It also unpacked them. One of the unpacked items is a directory (e.g.
qtbase-opensource-src-5.15.8+dfsg). This is the directory where we will compile the libraries. For convenience, define an environment variable to refer to this directory path. Basically, we want something like QtBaseBuildDIR="${QtBaseSrcDIR}/qtbase-opensource-src-5.15.8+dfsg", but it is possible the directory will be named differently for different versions of the source. So, the find command below finds the unpacked directory name and sets it to the environment variable. The directory name could also be determined by listing using ls -F from the command line.
QtBaseBuildDIR="$(find "${QtBaseSrcDIR}" -maxdepth 1 -mindepth 1 -type d -print)" && echo "${QtBaseBuildDIR}"
- Create a dedicated version of the source for this build. Ignore any warnings about DEBEMAIL or EMAIL environment variables, as we have no intention of sharing the results of our specific updates. The
dch or debchange commands might not be available on non-Debian based systems. It seems likely that this command can be skipped without breaking anything, but I did not test or verify this in any way.
cd "${QtBaseBuildDIR}" && dch --local "localver" "Modifications to locale settings for custom settings"
- In order to modify the date and/or time formats, CLDR data is needed. It can download from the http://cldr.unicode.org/ website's download page (http://cldr.unicode.org/index/downloads). There are several versions available. This step sets an environment variable to the version number to download. I had difficulty when I tried to use the latest version, so I used the same one that was used by the QtBase libraries in the Debian source package. The CLDR data is used to create a header file named
qlocale_data_p.h and the existing header file specifies which CLDR version was used. The command below extracts the version out of the file. It should be something like "39" or "31.0.1" . Other versions might or might not work. Any desired version number can be set by setting CLDRversion to the version desired. For example, CLDRversion="39". There probably is a better way to extract the version number from the file.
QLocaleDataFile="$(find "${QtBaseBuildDIR}" -name "qlocale_data_p.h" -size +100k)" && echo "${QLocaleDataFile}"
CLDRversion="$(grep "Common Locale Data Repository" "${QLocaleDataFile}" | awk -F " " '{ print $NF }' | awk '{ sub(/v/,""); print }')" && echo "${CLDRversion}"
- Download the CLDR file archive.
cd "${CLDRDIR}" && curl "http://unicode.org/Public/cldr/${CLDRversion}/core.zip" --output "${CLDRDIR}"/core.zip
- Extract the CLDR files
unzip "${CLDRDIR}"/core.zip -d "${CLDRDIR}"
- The
"${CLDRDIR}/common/main" directory contains xml files that could be modified to change the default locale formats. However, making edits to the intermediate file, localesForQt.xml, produced in the next step is easier and is what these instructions will cover.
- Process the CLDR files to make the intermediate locale file,
localesForQt.xml with file placed in "${TOPDIR}". This step will take several minutes and will generate a bunch of "skipping defaultContent" and "skipping file" messages. The messages can be ignored. Setting PYTHONDONTWRITEBYTECODE=1 is optional, but doing this step saves deleting or accounting for the python byte code files that would otherwise get created when the scripts run.
export PYTHONDONTWRITEBYTECODE=1
python2.7 "${QtBaseBuildDIR}"/util/locale_database/cldr2qlocalexml.py "${CLDRDIR}" > "${TOPDIR}"/localesForQt.xml
- Use a text editor to modify the intermediate locale file as desired.
- Each locale in the file has about 69 lines with locale settings.
- Find the corresponding locale (
//localeDatabase/localeList/locale/) section where modifications are desired.
- Normally, this corresponds to the locale that you are currently using in KDE. In any case, it will be the locale that you will want KDE to use after these modifications.
- Search for a language or a country to find which section to modify. For example, search for "UnitedStates" and find the locale block corresponding to "American English" language and "United States" country. Searching for "American English" (with the space between the two words) took me right to the block that I wanted to modify.
- References below have links to documentation on how to set the fields. Look at QtDate and QtTime documentation if modifying the date and time formats. Other formats can be adjusted as well.
sensible-editor "${TOPDIR}/localesForQt.xml"
Some example changes (to the "United States" "American English" locale, for example) :
WAS:
<longDateFormat>dddd, MMMM d, yyyy</longDateFormat>
<shortDateFormat>M/d/yy</shortDateFormat>
<longTimeFormat>h:mm:ss AP t</longTimeFormat>
<shortTimeFormat>h:mm AP</shortTimeFormat>
NOW:
<longDateFormat>dddd, MMMM dd, yyyy</longDateFormat>
<shortDateFormat>yyyy-MM-dd</shortDateFormat>
<longTimeFormat>HH:mm:ss t</longTimeFormat>
<shortTimeFormat>HH:mm</shortTimeFormat>
- Use provided script to generate C++ code from the intermediate locale file.
python2.7 "${QtBaseBuildDIR}"/util/locale_database/qlocalexml2cpp.py "${TOPDIR}"/localesForQt.xml "${QtBaseBuildDIR}"
- Commit the modifications to a patch file. Name the patch
"localver_locale_modification.diff" or something similar. An editor will open where the modifications can be documented.
cd "${QtBaseBuildDIR}" && dpkg-source --commit
- Build all of the QtBase libraries. This step will take a long time.
Upon completion, this step will leave many .deb files in
"${QtBaseSrcDIR}". Note that all of the packages have "localver" in the name. This can be useful for determining which packages were installed from source from these modifications.
cd "${QtBaseBuildDIR}" && debuild -i -us -uc -b
- Make a local repository to hold the Debian packages just created. I used,
"/usr/local/myrepository". Please use full path name when setting MyRepository.
MyRepository="/usr/local/myrepository"
sudo mkdir -p "${MyRepository}"
- Copy the Debian packages into the local repository. The command below, does not copy the dbgsym versions of the packages.
sudo find "${QtBaseSrcDIR}" -maxdepth 1 -mindepth 1 -type f -name \*localver\*.deb ! -name \*dbgsym\* -execdir cp \{\} "${MyRepository}" \;
- Generate the index files needed by apt when accessing the local repository.
sudo bash -c "cd \"${MyRepository}\" && apt-ftparchive packages ./ | gzip > \"${MyRepository}\"/Packages.gz"
- Add the local repository to the sources.list for apt. Note, the
apt-add-repository command used above when installing Python2, doesn't seem to work correctly for local repositories.
sudo bash -c "echo deb [trusted=yes] file://\"${MyRepository}\"/ ./ > /etc/apt/sources.list.d/local_kde_repository.list"
- Install all of the Debian packages in the local repository
sudo apt update
sudo apt install $(zcat "${MyRepository}"/Packages.gz | grep '^Package: ' | cut -c10- | sort)
- Mark these locally installed packages so that they won't be upgraded by automatic updates
sudo apt-mark hold $(zcat "${MyRepository}"/Packages.gz | grep '^Package: ' | cut -c10- | sort)
- Open "System Settings"/Personalization/Regional Settings/Region & Language and set all the options to the desired locale(s) (e.g.
"en_US"). The setting should match the country and region whose locale was modified.
- Logout or reboot and then log in for settings to take effect.
Instructions for Making a Custom glibc Locale for Setting Formats
This can be used with or without KDE and with or without the above instructions for modifying the KDE locale settings.
- View existing locale settings from command line.
locale
- If running KDE, view the KDE locale settings.
PlasmaLocaleRC="${XDG_CONFIG_HOME:-${HOME}/.config}/plasma-localerc"
[ -f "${PlasmaLocaleRC}" ] && cat "${PlasmaLocaleRC}"
- View the list of locales in
/usr/share/i18n/locales
ls /usr/share/i18n/locales
- Using existing locale settings, the KDE locale settings (if any), and the set of locales in
/usr/share/i18n/locales, select the base name for the modified output locale. Also select the name from the list of files in /usr/share/i18n/locales that will be the original locale to be modified.
- Choose a location to store your custom locale.
MyLocaleDIR="${XDG_DATA_HOME:-${HOME}/.local/share}/locale"
mkdir -p "${MyLocaleDIR}"
cd "${MyLocaleDIR}"
- Copy original locale definition into local destination
cp -i "/usr/share/i18n/locales/${OriginalLocaleName}" "${MyLocaleDIR}/${ModifiedBaseName}@custom"
- For date and time formats, reviewing the man page for
strftime can be helpful.
man strftime
- Edit the custom locale definition to have the desired formats, replacing the the formats to be changed with the desired formats.
- Note that most of the files in
/usr/share/i18n/locales will use other files or parts of other files in /usr/share/i18n/locales using the include or copy directives. If the file you are modifying in this step has one of these directives in a section you wish to edit, you might want to copy these included or copied files or parts of files into the custom file being edited. Or maybe, choosing one of those files as the OriginalLocaleName in step D would have been a better choice. In any case, other files in /usr/share/i18n/locales can be used as examples.
sensible-editor "${MyLocaleDIR}/${OriginalLocaleName}@custom"
%
% Appropriate date and time representation (%c)
d_t_fmt "%a %F %T %Z"
% above is the same as: d_t_fmt "%a %Y-%m-%d %H:%M:%S %Z"
%
% Appropriate date representation (%x)
d_fmt "%F"
% above is the same as: d_fmt "%Y-%m-%d"
%
% Appropriate time representation (%X)
t_fmt "%T"
% above is the same as t_fmt "%H:%M:%S"
%
% Appropriate AM/PM time representation (%r)
t_fmt_ampm "%T"
% above is also t_fmt, no need for anything different for 24H time
%
% Appropriate date and time representation for date(1)
date_fmt "%a %F %T %Z"
% above is the same as d_t_fmt
%
% Strings for AM/PM
am_pm "";""
% no need for am/pm for 24H time
%
- Make the modified locale. These instructions and the command below assume that the desire is to replace the existing locale settings with the new custom ones. That is, the new custom locale settings will use the same name as an existing set of locale settings. If this isn't desired, adding
@custom to the end of the name before the -v in the command below can be used to give the custom settings a different name. Note, that the instructions here don't completely cover that case, and there could be some issues when first logging in, when starting bash, or when connecting to remote hosts with ssh. For the case covered by these instructions, the original locale can still be accessed by unsetting LOCPATH.
localedef -f UTF-8 -i "${MyLocaleDIR}/${OriginalLocaleName}@custom" "${MyLocaleDIR}/${ModifiedBaseName}.utf8" -v
The encoding name (e.g., UTF-8) is normalized by glibc, so that UTF-8, UTF8, utf-8, utf8, etc., all refer to the same encoding.
- Edit the
.bashrc file to make the newly generated locale settings the defaults
sensible-editor "${HOME}"/.bashrc
Put something like this, except use the ModifiedBaseName for en_US.
# LOCPATH determines where locale settings are found
export LOCPATH="${XDG_DATA_HOME:-${HOME}/.local/share}/locale":/usr/lib/locale
# set the locale environment variables
export LANG=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
export LC_NUMERIC=en_US.UTF-8
export LC_TIME=en_US.UTF-8
export LC_COLLATE=C
export LC_MONETARY=en_US.UTF-8
export LC_MESSAGES=en_US.UTF-8
export LC_PAPER=en_US.UTF-8
export LC_NAME=en_US.UTF-8
export LC_ADDRESS=en_US.UTF-8
export LC_TELEPHONE=en_US.UTF-8
export LC_MEASUREMENT=en_US.UTF-8
export LC_IDENTIFICATION=en_US.UTF-8
#
# optional, set the time format for the ls command
export TIME_STYLE=long-iso
#
- Logout or reboot and then log in to test.
References
kde.org bug report:
https://bugs.kde.org/show_bug.cgi?id=340982
Qt Bug Report:
https://bugreports.qt.io/browse/QTBUG-58351
Stackexchange question on how to modify date/time formats in KDE 5:
How to hack and modify a predefined date time format of KDE 5 that comes with Debian 9.2.1 Stretch?
Glen Whitney step-by-step for OpenSUSE Tumbleweed:
How to hack and modify a predefined date time format of KDE 5 that comes with Debian 9.2.1 Stretch?
Qt QDateTime Class documentation:
https://doc.qt.io/qt-5/qdatetime.html
Qt QTime Class documentation:
https://doc.qt.io/qt-5/qtime.html
Qt QTime format parameters:
https://doc.qt.io/qt-5/qtime.html#toString
Qt QDate Class documentation:
https://doc.qt.io/qt-5/qdate.html
Qt QDate format parameters:
https://doc.qt.io/qt-5/qdate.html#toString
Glibc locales:
https://sourceware.org/glibc/wiki/Locales
Debian Building Tutorial:
https://wiki.debian.org/BuildingTutorial
Debian FAQ - source packages:
https://www.debian.org/doc/manuals/debian-faq/pkg-basics.en.html#sourcepkgs
Debian FAQ - source build:
https://www.debian.org/doc/manuals/debian-faq/pkg-basics.en.html#sourcebuild
How to modify an existing locale:
Installing Python 2 on Debian 12:
https://old.reddit.com/r/linuxquestions/comments/1aejta0/is_there_any_way_to_get_python_2_on_debian_12/
How to avoid pyc files:
https://stackoverflow.com/questions/154443/how-to-avoid-pyc-files
ksh_DE) that are not present in/usr/share/i18n/locales. Thefind / -iname ksh_dedoes not even return any results. Bad KDE. BAD. Sit!find / -iname '*ksh_de*'.