11

I would like to hack and modify a predefined date time format of KDE 5 on Debian 9.2.1 Stretch.

A predefined format can be selected from the list of predefined formats at Kickoff Launcher > Computer > System Settings > Personalization > Regional Settings > Formats.

(For the screen shot of the Formats settings dialog, see https://superuser.com/q/1162283 on the SuperUser site.)

The effect of the format appears on the Formats settings dialog itself, and also appears on the Date field of the Details view of the Dolphin File Manager of the KDE desktop, and also the Properties of any file on Dolphin.

Unfortunately, none of the predefined formats suits me. The date time format of en_US ("United States - American English") is particularly terrible from my viewpoint. On the other hand, the short date time format of en_SE ("Sweden - English") is ISO 8601, and is close to what I want. Nevertheless, even en_SE does not completely satisfy me; especially its long format disappoints me.

This Formats settings dialog never lets you freely create custom formats. It only gives you a choice from predefined formats.

Thus, I would like to hack and modify a predefined format. Please let me know how.

The directory /usr/share/i18n/locales contains format files. The file names are identical to the format names such as en_US, en_GB, fr_FR and so on. However, the KDE that came with Debian 9.2.1 does not care about the format files in /usr/share/i18n/locales. Modification to these format files or even deletion of all of these files never affects the behavior of the KDE on Debian 9.2.1. This directory even lacks en_SE, and nevertheless en_SE appears in the Formats settings dialog.

I wonder if the predefined formats are hard-coded in KDE.

Note that Debian 9.0 Stretch was released on 2017-06-17. The versions of KDE components that came with Debian 9.2.1 follow:

plasmashell --version
# plasmashell 5.8.6

kf5-config --version
# Qt: 5.7.1
# KDE Frameworks: 5.28.0
# kf5-config: 1.0

TheEzekielProject claims in his post (https://www.linuxquestions.org/questions/linuxquestions-org-member-success-stories-23/guide-to-setting-custom-date-format-in-recent-versions-of-kde-4175595458-print/) that he managed to create a custom date time format by modifying a format file in the directory /usr/share/i18n/locales. The systems he tested are Kali Linux 2016.2 rolling with KDE Plasma 5.8.2 and KDE Frameworks 5.27.0, and Kubuntu 16.10 with KDE Plasma 5.7.5 and KDE Frameworks 5.26.0. His systems are older than mine.

I tried his method. In a format file, under LC_TIME, I changed d_t_fmt, d_fmt, t_fmt and t_fmt_ampm, and executed locale-gen, and so on. However, his method has turned out to have no effect on the KDE on Debian 9.2.1. Also a comment to his post complains that his method fails on Neon (plasma 5.10).

By the way, my question is not a duplicate of questions/1162283/use-iso-time-and-date-format-in-kde-5 on the SuperUser site. The question 1162283 asked for ISO date time format, and it has been fulfilled by the answer by Marco Lussetti, that is, by simply selecting en_SE from the list of predefined formats. My question asks for a hack to go beyond predefined formats.

5
  • Ask your question directly to KDE developers ( forum.kde.org ), they know much more about kde than us. Commented Dec 14, 2017 at 10:46
  • I wish someone to ask KDE developers at the KDE forum (forum.kde.org), and post an answer back here. In general, hidden configuration options for KDE products that cannot be changed via the normal Settings dialog can be changed via the command "kwriteconfig5" or "kwriteconfig". Examples of such hidden configuration options are found on the following two web pages: "docs.kde.org/trunk5/en/pim/kmail2/…" and "reddit.com/r/kde/comments/55udc1/…". Commented Jan 8, 2018 at 13:01
  • This is further solidified by the list of locales shown in the Plasma UI containing elements (e.g. ksh_DE) that are not present in /usr/share/i18n/locales. The find / -iname ksh_de does not even return any results. Bad KDE. BAD. Sit! Commented Jan 27, 2018 at 13:35
  • Correction: Of course I meant find / -iname '*ksh_de*'. Commented Jan 27, 2018 at 14:06
  • I'm surprised by the lack of expletives on this page. For a regular user, their employment would be warranted. The bug at the KDE tracker is closed since the responsibility was moved to Qt. Qt has already made clear that they won't accept it. Commented Jul 3, 2024 at 14:02

4 Answers 4

9

It took me half a day to (almost) fully investigate this, but I think I found how to do it, and you’re not gonna like it …

The Solution:

In a nutshell,

KDE just uses QT’s QLocale. Which itself uses hard-coded data inside qlocale_data_p.h, deep in QT’s core library code.

This data is apparently manually generated from the Unicode Consortium’s “Common Locale Data Repository”, using several Python scripts inside util/local_database/ of the QT source code package. Which itself is not even part of the source code, I am certain. Let alone, using any kind of configuration or data files on your computer.

So the only way to do this, is to …

  1. Download the CLDR files, either as a package, at http://unicode.org/Public/cldr/latest/core.zip (or cldr-common-*.zip, they both seem to contain the same), or at https://www.unicode.org/repos/cldr/trunk/, and extract the XML files under common/main/.
    Gentoo also has a package called app-i18n/unicode-cldr btw.
  2. Acquire the QT core source code, e.g. from your distribution’s repository, and unpack it.
  3. Use the scripts in util/local_database/ (like cldr2qlocalexml.py and qlocalexml2cpp.py), with your language of choice’s XML file, to re-generate the static qlocale_data_p.h.
  4. Then compile and install the package as normal.

And don’t forget to recompile all other packages that include qlocale_data_p.h.

Or, on Gentoo, make a lasting patch with:

ebuild $(equery w dev-qt/qtcore:5) prepare
pushd /var/tmp/portage/dev-qt/qtcore-5*/work/ # assuming default Portage build directory
mv qtbase-opensource-src-5.9.3 a
cp -a a b

NOW make the above changes in b, and not in a. Then continue with:

mkdir -p /etc/portage/patches/dev-qt/$(basename $(dirname $(pwd))) # only for this version
#mkdir -p /etc/portage/patches/dev-qt/qtcore # for all versions
diff -ur a b > /etc/portage/patches/dev-qt/qtcore*/my-locale.patch
rm -rf a b
popd
ebuild $(equery w dev-qt/qtcore:5) clean
# Rebuild all packages that depend on it, just to be sure. May be optional.
emerge -1 dev-qt/qtcore:5 $(equery d dev-qt/qtcore:5 | sed 's/^/=/')

Final thoughts

To be perfectly frank, I didn’t check if those Python scripts actually worked by just passing an XML file. As, at that point, I just stopped bothering, and wanted to kill it with fire. :)

Patrick Bateman axe murderer

If anyone wants to actually do it in practice, please report, and I will update this answer. (Or do it yourself, if you can.)


Here’s how I got there:

  • I opened KDE’s time formats setting dialog, via right-click on the task bar clock.
  • Then, with htop I found the most recently started processes, which included the obvious kcmshell5 formats.
  • Using htop’s list open files feature on it, I filtered for “format”, and found /usr/lib64/qt5/plugins/kcm_formats.so.
  • With the help of Gentoo’s equery belongs /usr/lib64/qt5/plugins/kcm_formats.so I could identify the package kde-plasma/plasma-desktop.
  • After unpacking its source file, I quickly found kcms/formats/kcmformats.cpp, whose addLocaleToCombo used the QLocale, and included <QLocale> too.
  • This QLocale could then be found with locate -i QLocale to reside at /usr/include/qt[5]/QtCore/qlocale.h. It included some generated enumerations of the languages, scripts, etc.
  • Another equery belongs /usr/include/qt[5]/QtCore/qlocale.h pointing me to dev-qt/qtcore/qtcore, and unpacking the source file later…
  • … I already had a gut feeling, that it was all generated with some tool. So I looked into util/ and found util/local_database/README stating “local_database is used to generate qlocale data from the Common Locale Data Repository (The database for localized names (like date formats, country names etc)).”.
  • Having never heard of that, I looked it up, and it’s apparently by the Unicode Consortium. The code of cldr2qlocalexml.py was not very useful though, as it is called with the path to a directory containing the CLDR locales. Its result is used for qlocalexml2cpp.py though, which generates the file src/corelib/tools/qlocale_data_p.h, which includes huge hard-coded tables of all the locale data. And that file already existed in the source. So… yep, it’s (partially?) hard-coded.
    facepalm
  • But the CLDR XML files were nowhere to be found. So I assume it just uses the previously prepared qlocale_data_p.h. Which is not very in the spirit of open source. But at least you can do it yourself, as described above.
6
  • 3
    It is absurd that KDE and GNOME use hardcoded date format options, or don't at least include an ISO-8601 or RFC-3339 compliant hardcoded option. Both XFCE and Tint2 panels allow arbitrary strftime strings (like in date command). Honestly the simple fact that XFCE lets me display time in an arbitrary format is a huge advantage to me, because the GNOME time widget is awful to look at, and while KDE allows for more detail it doesn't comply with standards. Commented Apr 30, 2018 at 18:37
  • Would be grateful, if somebody can write more detailed guide on this. I'm new to linux ecosystem and got lost on step 3. Commented Oct 7, 2018 at 13:50
  • Seriously, why does a 24-hour clock setting show only a single digit for the hours??? Even WinBlows allows you to set a custom time format. Commented Dec 4, 2022 at 5:20
  • @theferrit32: You can use any other widget of your choice though. (I don’t know if there is a widget that allows using the output of arbitrary commands, or maybe a HTML file with embedded arbitrary commands. Because what’s wrong with date?) … But yeah, I’m currently writing my own Linux-based OS (building on Plan9 ideas), so … :) Commented Dec 9, 2022 at 14:00
  • @Sevastyan: I forgot this stuff, but presumably, as a general idea for these things, you can run python3 cldr2qlocalexml.py as a command and pass it a XML file from that CLDR collection, to obtain a qlocale_data_p.h. How the passing and obtaining is done, can probably be seen in that .py file. (As parameters or by piping usually.) Maybe there is a --helpto find out the easy way. … Sorry, I just came back here after a long time out of curiosity. Commented Dec 9, 2022 at 14:05
3

If anyone is interested, here are the steps I took to modify and compile the QT Core libraries on Debian 10. This allowed me to set the date and time formats the way I wanted for the KDE PIM (kontact, and in particular korganizer). It is a bit of a kludge, but it works for me. I should have done it years ago. It is unfortunate that changing a date format or time format requires multiple hours to perform.

I used the helpful step-by-step posted by Glen Whitney to get me started with this approach.

Notes: I started with a minimal Debian 10 install. I assume that sudo is installed to allow for commands to be executed as root. The commands below assume that bash is the shell.

  1. Install necessary requirements for building source packages in Debian.

    sudo apt install build-essential fakeroot devscripts
    
  2. Install other needed dependencies.

    sudo apt install python2
    sudo apt-get build-dep qtbase-opensource-src
    
  3. Make a directory in which to work. I'm using QtLocaleFix as the top level directory in which to work.

    mkdir QtLocaleFix
    cd QtLocaleFix
    TOPDIR="${PWD}"
    
  4. Create three sub-directories, one for the QtBase source code, one for the CLDR (Common Locale Data Repository), and one for convenience for the scripts needed to convert the CLDR locale information to the format needed by the QtBase libraries.

    QtBaseSrcDIR="${TOPDIR}/QtBaseSrc"
    mkdir "${QtBaseSrcDIR}"
    CLDRDIR="${TOPDIR}/CLDR"
    mkdir "${CLDRDIR}"
    CLDRScriptsDIR="${TOPDIR}/CLDRScripts"
    mkdir "${CLDRScriptsDIR}"
    
  5. Get the source code for the QtBase libs (libqt5core5a).

    cd "${QtBaseSrcDIR}"
    apt source qtbase-opensource-src
    
  6. 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.11.3+dfsg1). 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.11.3+dfsg1", 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.

    QtBaseBuildDIR="$(find "${QtBaseSrcDIR}" -maxdepth 1 -mindepth 1 -type d -print)" && echo "${QtBaseBuildDIR}"
    
  7. Create a dedicated version of the source for this build.

    cd "${QtBaseBuildDIR}"
    dch --local "localver" "Modifications to locale settings for date and time formats"
    
  8. Copy the CLDR conversion scripts to "${CLDRScriptsDIR}". This step could be skipped and the scripts could be run directly from the existing "${QtBaseBuildDIR}" sub-directory. However, doing this copy step saves deleting or accounting for the python byte code files that get created when the scripts run.

    cp -pr "${QtBaseBuildDIR}"/util/local_database/* "${CLDRScriptsDIR}"
    
  9. 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 "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="31.0.1". 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}"
    
  10. Download the CLDR file archive.

    cd "${CLDRDIR}"
    curl "http://unicode.org/Public/cldr/${CLDRversion}/core.zip" --output "${CLDRDIR}/core.zip"
    
  11. Extract the CLDR files

    unzip core.zip
    
  12. The next couple steps are where predefined date and time (or other locale formats) can be modified before building the QtBase libraries. The specific changes to make depend on the formats that are desired. Following an approach like the one Glen Whitney gave, has edits being made to a file or files in "${CLDRDIR}/common/main". It is also possible to apply the edits to the intermediate locale file, localesForQt.xml. The intermediate locale file is created in step 14.

    Make a list of desired changes and review documentation before continuing.

    The specifics of what to change and how to change them are beyond scope of these instructions. However, here are a few hints and notes.

    • If editing the CLDR files:

      • For English language modifications, could modify "${CLDRDIR}/comman/main/en.xml", as Glen Whitney did.
      • Look at the settings under //ldml/dates/calendars/calendar[@type="gregorian"]/dateFormats/ or //ldml/dates/calendars/calendar[@type="gregorian"]/timeFormats/
      • References below have links to documentation on how to set the fields. (Note that the way the formats are specified is different for the downloaded CLDR files than for the intermediate locale file. Look at Unicode LDML documentation if modifying the CLDR files.)
      • Some changes to the CLDR files won't propagate to the intermediate locale file. Some items in the CLDR files don't have an analogue in the Qt locales framework.
    • If editing the intermediate file:

      • Each locale in the file has about 55 lines with locale settings.
      • Find the corresponding //localeDatabase/localeList/locale/ section where modifications are desired.
      • 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. Actually, searching for "United States" or "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. (Note that the way the formats are specified is different for the intermediate locale file than for the downloaded CLDR files. Look at QtDate and QtTime documentation if modifying the intermediate locale file.)
    • Editing the intermediate locale file is probably more straightforward for most use cases.

  13. Use a text editor to modify any files in "${CLDRDIR}/common/main" where changes are desired. As described above it is not necessary to change any files in this step. The intermediate locale file might be easier to edit.

    sensible-editor "${CLDRDIR}"/common/main/en.xml
    
  14. 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 might even give the impression that files modified in the previous step were skipped. Don't panic. The messages appear to be misleading.

    "${CLDRScriptsDIR}"/cldr2qlocalexml.py "${CLDRDIR}"/common/main > "${TOPDIR}/localesForQt.xml"
    
  15. Use a text editor to modify or review the intermediate locale file if desired. If changes were made to the CLDR files before generating the intermediate locale file, this is an opportunity to check that any desired changes made it into the intermediate locale file.

    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>
    
  16. Use provided script to generate C++ code from the intermediate locale file.

    "${CLDRScriptsDIR}"/qlocalexml2cpp.py "${TOPDIR}/localesForQt.xml" "${QtBaseBuildDIR}" 
    
  17. 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
    
  18. Build all of the QtBase libraries. This step will take a long time.

    debuild -us -uc
    
  19. Upon completion, the previous step will leave many .deb files in "${QtBaseSrcDIR}". Install them with dpkg. Note that all of the packages have "localver" in the name. This can be useful for determining which packages were installed from source. After the initial install attempt with dpkg, if there are missing dependencies, they can be fixed with sudo dpkg --configure -a and sudo apt-get -f install. Then the installation of the "localver" packages can be repeated.

    find "${QtBaseSrcDIR}" -maxdepth 1 -mindepth 1 -type f -name \*localver\*.deb ! -name \*dbgsym\* -print0 | xargs -0 sudo dpkg -i
    sudo dpkg --configure -a
    sudo apt-get -f install
    find "${QtBaseSrcDIR}" -maxdepth 1 -mindepth 1 -type f -name \*localver\*.deb ! -name \*dbgsym\* -print0 | xargs -0 sudo dpkg -i
    
  20. Open "System Settings"/Personalization/Regional Settings/Formats and set the Region to the desired locale(s) (e.g. "en_US"). The setting should match the country and region whose locale was modified. Click on "Detailed Settings" and set the same locale across all of the sub options. (I didn't get all of my updates until I turned on and set explicitly all of the detailed settings.) Logout or reboot for settings to take effect.

References:

kde.org bug report: https://bugs.kde.org/show_bug.cgi?id=340982

Unicode Locale Data Markup Language (LDML) Part 4: Dates # Date Field Symbol Table: https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table

Qt QTime format parameters: https://doc.qt.io/qt-5/qtime.html#toString

Qt QDate format parameters: https://doc.qt.io/qt-5/qdate.html#fromString

References truncated due to having more than the allowed number of links.

1
  • 👍 for that bold sentence alone. :D Commented Dec 9, 2022 at 14:07
1

Over a year later, AFAICT the situation is exactly the same, and I have just done this process on OpenSUSE Tumbleweed to set the date formats the way I want for en_US. Here's the step-by-step, replace [SOMEPATH] (including the brackets) to your liking, and you may want to update the version number of CLDR if it's bumped from 35.1 since I posted this:

  1. sudo zypper si libqt5-qtbase # That installs the source rpm for Qt Core
  2. cd /usr/src/packages/SPECS
  3. sudo rpmbuild -bp libqt5-qtbase.spec
  4. cd [SOMEPATH]
  5. curl http://unicode.org/Public/cldr/35.1/core.zip --output core.zip
  6. unzip core.zip
  7. nano common/main/en.xml # or whichever language/region you want to change -- find the date formats you want to change or whatever other parameters of the local and edit to your heart's content.
  8. cd /usr/src/packages/BUILD/qtbase-everywhere-src-5.13.0/util/local_database/
  9. ./cldr2qlocalexml.py [SOMEPATH]/common/main > [SOMEPATH]/localesForQt.xml
  10. sudo ./qlocalexml2cpp.py [SOMEPATH]/localesForQt.xml /usr/src/packages/BUILD/qtbase-everywhere-src-5.13.0/
  11. cd /usr/src/packages/SPECS
  12. sudo rpmbuild --noprep --noclean -bb libqt5-qtbase.spec # Go watch a movie, depending on how fast your computer is...
  13. When the build is done, there should be many RPMS created in /usr/src/packages/RPMS/[your_architecture]. Change directories into that directory.
  14. sudo zypper install *Core*
  15. Reboot and log back in and you should see your changes :-)

See, isn't configuring KDE/Qt fun and convenient? ;-)

0

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
  1. 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
  1. Install other needed dependencies.
sudo apt build-dep qtbase-opensource-src
sudo apt install curl software-properties-common
  1. 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
  1. Make a directory in which to work. I used, QtLocaleFix in my home directory.
TOPDIR="${HOME}/QtLocaleFix"
mkdir -p "${TOPDIR}"
cd "${TOPDIR}"
  1. 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}"
  1. Get the source code for the QtBase libs (libqt5core5a).
 cd "${QtBaseSrcDIR}" && apt source qtbase-opensource-src
  1. 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}"
  1. 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"
  1. 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}"
  1. Download the CLDR file archive.
cd "${CLDRDIR}" && curl "http://unicode.org/Public/cldr/${CLDRversion}/core.zip" --output "${CLDRDIR}"/core.zip
  1. Extract the CLDR files
unzip "${CLDRDIR}"/core.zip -d "${CLDRDIR}"
  1. 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.
  2. 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
  1. Use a text editor to modify the intermediate locale file as desired.
  2. Each locale in the file has about 69 lines with locale settings.
  3. Find the corresponding locale (//localeDatabase/localeList/locale/) section where modifications are desired.
  4. 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.
  5. 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.
  6. 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>
    
  1. Use provided script to generate C++ code from the intermediate locale file.
python2.7 "${QtBaseBuildDIR}"/util/locale_database/qlocalexml2cpp.py "${TOPDIR}"/localesForQt.xml "${QtBaseBuildDIR}"
  1. 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
  1. 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
  1. 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}"
  1. 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}" \;
  1. Generate the index files needed by apt when accessing the local repository.
sudo bash -c "cd \"${MyRepository}\" && apt-ftparchive packages ./ | gzip > \"${MyRepository}\"/Packages.gz"
  1. 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"
  1. 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)
  1. 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)
  1. 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.
  2. 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.

  1. View existing locale settings from command line.
locale
  1. If running KDE, view the KDE locale settings.
PlasmaLocaleRC="${XDG_CONFIG_HOME:-${HOME}/.config}/plasma-localerc"
[ -f "${PlasmaLocaleRC}" ] && cat "${PlasmaLocaleRC}"
  1. View the list of locales in /usr/share/i18n/locales
ls /usr/share/i18n/locales
  1. 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.
  • The base name for the modified locale is just the language_region part of the locale name. For example, when existing settings use "en_US.UTF-8", the base name for the output locale would be "en_US".
    • If using KDE, the name should match what KDE is using.
  • The original locale to be modified often has the same name. That is, often both names are the same. For example, "en_US", in the example above would also be the name of the original locale to be modified.
    • The idea is to pick an original locale that is mostly what is wanted, so that only a few modifications need to be made. So, the easiest is often to just use the same name.
    • If unsure, using the same name for both is recommended, at least to start. Otherwise, "C" or "en_US" are also good choices.
    ModifiedBaseName="en_US"
    OriginalLocaleName="en_US"
    
  1. Choose a location to store your custom locale.
MyLocaleDIR="${XDG_DATA_HOME:-${HOME}/.local/share}/locale"
mkdir -p "${MyLocaleDIR}"
cd "${MyLocaleDIR}"
  1. Copy original locale definition into local destination
cp -i "/usr/share/i18n/locales/${OriginalLocaleName}" "${MyLocaleDIR}/${ModifiedBaseName}@custom"
  1. For date and time formats, reviewing the man page for strftime can be helpful.
man strftime
  1. 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"
  • For example:
%
% 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
%
  1. 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.

  1. 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
#
  1. 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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.