我想破解并修改 Debian 9.2.1 Stretch 上 KDE 5 的预定义日期时间格式。
可以从 Kickoff Launcher > 计算机 > 系统设置 > 个性化 > 区域设置 > 格式的预定义格式列表中选择预定义格式。
(有关格式设置对话框的屏幕截图,请参见https://superuser.com/q/1162283在超级用户网站上。)
格式的效果出现在“格式设置”对话框本身上,并且还出现在 KDE 桌面的 Dolphin 文件管理器的“详细信息”视图的“日期”字段中,以及 Dolphin 上任何文件的“属性”中。
不幸的是,没有一个预定义的格式适合我。en_US
在我看来,(“美国 - 美式英语”)的日期时间格式特别糟糕。另一方面,en_SE
(“瑞典 - 英语”)的短日期时间格式是 ISO 8601,并且接近我想要的。尽管如此,甚至还en_SE
不能完全令我满意;尤其是它的长格式让我失望。
此格式设置对话框绝不允许您自由创建自定义格式。它只让您从预定义的格式中进行选择。
因此,我想破解并修改预定义的格式。请让我知道如何做。
该目录/usr/share/i18n/locales
包含格式文件。文件名与格式名称相同,例如、en_US
等。然而,Debian 9.2.1 附带的 KDE 并不关心.对这些格式文件的修改甚至删除所有这些文件都不会影响 Debian 9.2.1 上 KDE 的行为。该目录甚至缺少,但仍然出现在“格式设置”对话框中。en_GB
fr_FR
/usr/share/i18n/locales
en_SE
en_SE
我想知道 KDE 中是否对预定义格式进行了硬编码。
请注意,Debian 9.0 Stretch 于 2017 年 6 月 17 日发布。 Debian 9.2.1 附带的 KDE 组件版本如下:
plasmashell --version
# plasmashell 5.8.6
kf5-config --version
# Qt: 5.7.1
# KDE Frameworks: 5.28.0
# kf5-config: 1.0
以西结项目在他的帖子中声称(https://www.linuxquestions.org/questions/linuxquestions-org-member-success-stories-23/guide-to-setting-custom-date-format-in-recent-versions-of-kde-4175595458-print/)他通过修改目录中的格式文件成功创建了自定义日期时间格式/usr/share/i18n/locales
。他测试的系统是带有 KDE Plasma 5.8.2 和 KDE Frameworks 5.27.0 的 Kali Linux 2016.2,以及带有 KDE Plasma 5.7.5 和 KDE Frameworks 5.26.0 的 Kubuntu 16.10。他的系统比我的旧。
我尝试了他的方法。在格式文件中,在 下LC_TIME
,我更改了d_t_fmt
、d_fmt
、t_fmt
和t_fmt_ampm
,并执行了locale-gen
,等等。然而,事实证明他的方法对 Debian 9.2.1 上的 KDE 没有任何影响。对他的帖子的评论还抱怨他的方法在 Neon (plasma 5.10) 上失败。
questions/1162283/use-iso-time-and-date-format-in-kde-5
顺便说一句,我的问题与超级用户网站上的问题不重复。问题 1162283 要求 ISO 日期时间格式,Marco Lussetti 的回答已经满足了该问题,即只需en_SE
从预定义格式列表中进行选择即可。我的问题要求进行超越预定义格式的破解。
答案1
我花了半天时间(几乎)完全调查了这一点,但我想我找到了如何做到这一点,而你不会喜欢它......
解决方案:
简而言之,
KDE 仅使用 QT 的QLocale
.它本身使用qlocale_data_p.h
QT 核心库代码深处的硬编码数据。
该数据显然是从 Unicode 联盟的“公共区域设置数据存储库util/local_database/
”,使用QT 源代码包内的多个 Python 脚本。其本身就是不是甚至是部分源代码,我确信。更不用说在计算机上使用任何类型的配置或数据文件。
因此,做到这一点的唯一方法是……
- 下载 CLDR 文件(作为包),网址为http://unicode.org/Public/cldr/latest/core.zip(或 cldr-common-*.zip,它们似乎都包含相同的内容),或位于https://www.unicode.org/repos/cldr/trunk/,并提取 .xml 下的 XML 文件
common/main/
。
Gentoo 还有一个名为app-i18n/unicode-cldr
btw 的软件包。 - 获取 QT 核心源代码,例如从您的发行版存储库中获取,并将其解压。
util/local_database/
使用(如cldr2qlocalexml.py
和)中的脚本qlocalexml2cpp.py
以及您选择的语言的 XML 文件,重新生成静态qlocale_data_p.h
.- 然后正常编译并安装该包。
并且不要忘记重新编译所有其他包含qlocale_data_p.h
.
或者,在 Gentoo 上,使用以下命令制作持久补丁:
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
现在在 中进行上述更改b
,而不是在 中进行a
。然后继续:
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/^/=/')
最后的想法
坦白说,我并没有通过传递 XML 文件来检查这些 Python 脚本是否真的有效。因为,在那一点上,我只是不再打扰,并且想要用火杀死它。 :)
如果有人想在实践中真正做到这一点,请报告,我将更新这个答案。 (或者如果可以的话,自己做。)
我是这样到达那里的:
- 我通过右键单击任务栏时钟打开了 KDE 的时间格式设置对话框。
- 然后,
htop
我找到了最近启动的进程,其中包括明显的kcmshell5 formats
. - 使用
htop
它的l
ist 打开文件功能,我过滤了“格式”,并找到了/usr/lib64/qt5/plugins/kcm_formats.so
. - 在 Gentoo 的帮助下
equery belongs /usr/lib64/qt5/plugins/kcm_formats.so
我可以识别这个包kde-plasma/plasma-desktop
。 - 解压它的源文件后,我很快找到了
kcms/formats/kcmformats.cpp
,它addLocaleToCombo
使用了QLocale
,并且<QLocale>
也包含了 。 QLocale
然后可以找到它并locate -i QLocale
驻留在/usr/include/qt[5]/QtCore/qlocale.h
。它包括一些生成的语言、脚本等枚举。- 另一个
equery belongs /usr/include/qt[5]/QtCore/qlocale.h
指向我dev-qt/qtcore/qtcore
,稍后解压源文件...... - ......我已经有一种直觉,这一切都是由某种工具生成的。所以我调查
util/
并发现util/local_database/README
“local_database 用于从公共区域设置数据存储库(本地化名称数据库(如日期格式、国家/地区名称等)。”。 - 从来没有听说过这个,我查了一下,显然是由统一码联盟。不过,代码
cldr2qlocalexml.py
并不是很有用,因为它是通过包含 CLDR 语言环境的目录的路径来调用的。它的结果用于qlocalexml2cpp.py
生成文件src/corelib/tools/qlocale_data_p.h
,其中包括巨大的 硬编码的所有区域设置数据的表。并且该文件已经存在于源中。所以……是的,它(部分?)是硬编码的。
- 但找不到 CLDR XML 文件。所以我假设它只是使用之前准备的
qlocale_data_p.h
.这不太符合开源精神。但至少你可以自己做,如上所述。
答案2
如果有人感兴趣,这里是我在 Debian 10 上修改和编译 QT Core 库所采取的步骤。这使我能够按照我想要的 KDE PIM(kontact,特别是 korganizer)的方式设置日期和时间格式。这有点混乱,但对我有用。我几年前就应该这么做了。 不幸的是,更改日期格式或时间格式需要几个小时才能执行。
我使用了 Glen Whitney 发布的有用的分步指南来帮助我开始使用这种方法。
注意:我从最小的 Debian 10 安装开始。我假设sudo
安装它是为了允许以 root 身份执行命令。下面的命令假设 bash 是 shell。
安装在 Debian 中构建源包的必要要求。
sudo apt install build-essential fakeroot devscripts
安装其他需要的依赖项。
sudo apt install python2 sudo apt-get build-dep qtbase-opensource-src
创建一个要在其中工作的目录。我正在使用它
QtLocaleFix
作为工作的顶级目录。mkdir QtLocaleFix cd QtLocaleFix TOPDIR="${PWD}"
创建三个子目录,一个用于 QtBase 源代码,一个用于 CLDR(公共区域设置数据存储库),另一个用于方便将 CLDR 区域设置信息转换为 QtBase 库所需的格式所需的脚本。
QtBaseSrcDIR="${TOPDIR}/QtBaseSrc" mkdir "${QtBaseSrcDIR}" CLDRDIR="${TOPDIR}/CLDR" mkdir "${CLDRDIR}" CLDRScriptsDIR="${TOPDIR}/CLDRScripts" mkdir "${CLDRScriptsDIR}"
获取 QtBase 库 (libqt5core5a) 的源代码。
cd "${QtBaseSrcDIR}" apt source qtbase-opensource-src
上一步下载了 QtBase 库的源文件。它还打开了它们的包装。解压后的项目之一是一个目录(例如
qtbase-opensource-src-5.11.3+dfsg1
)。这是我们将编译库的目录。为了方便起见,定义一个环境变量来引用该目录路径。基本上,我们想要类似的东西QtBaseBuildDIR="${QtBaseSrcDIR}/qtbase-opensource-src-5.11.3+dfsg1"
,但对于不同版本的源代码,该目录可能会以不同的方式命名。因此,find
下面的命令找到解压后的目录名称并将其设置为环境变量。目录名也可以通过列表来确定。QtBaseBuildDIR="$(find "${QtBaseSrcDIR}" -maxdepth 1 -mindepth 1 -type d -print)" && echo "${QtBaseBuildDIR}"
为此构建创建专用的源版本。
cd "${QtBaseBuildDIR}" dch --local "localver" "Modifications to locale settings for date and time formats"
将 CLDR 转换脚本复制到
"${CLDRScriptsDIR}"
.可以跳过此步骤,可以直接从现有"${QtBaseBuildDIR}"
子目录运行脚本。但是,执行此复制步骤可以节省删除或计算脚本运行时创建的 python 字节代码文件的时间。cp -pr "${QtBaseBuildDIR}"/util/local_database/* "${CLDRScriptsDIR}"
为了修改日期和/或时间格式,需要 CLDR 数据。它可以从下载http://cldr.unicode.org/网站的下载页面(http://cldr.unicode.org/index/downloads)。有多个版本可用。此步骤将环境变量设置为要下载的版本号。当我尝试使用最新版本时遇到了困难,因此我使用了 Debian 源代码包中的 QtBase 库所使用的相同版本。 CLDR 数据用于创建名为 的头文件
"qlocale_data_p.h"
,现有头文件指定使用哪个 CLDR 版本。下面的命令从文件中提取版本。它应该是类似的东西"31.0.1"
。其他版本可能会也可能不会。可以通过将 CLDRversion 设置为所需的版本来设置任何所需的版本号。例如,CLDRversion="31.0.1"
。可能有更好的方法从文件中提取版本号。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}"
下载 CLDR 文件存档。
cd "${CLDRDIR}" curl "http://unicode.org/Public/cldr/${CLDRversion}/core.zip" --output "${CLDRDIR}/core.zip"
提取 CLDR 文件
unzip core.zip
接下来的几个步骤是在构建 QtBase 库之前可以修改预定义的日期和时间(或其他区域设置格式)。要进行的具体更改取决于所需的格式。按照 Glen Whitney 给出的方法,对一个或多个
"${CLDRDIR}/common/main"
.还可以将编辑应用到中间语言环境文件localesForQt.xml
.中间区域设置文件是在步骤 14 中创建的。列出所需的更改并在继续之前查看文档。
更改内容以及如何更改的具体细节超出了这些说明的范围。不过,这里有一些提示和注意事项。
如果编辑 CLDR 文件:
- 对于英语语言修改,可以修改
"${CLDRDIR}/comman/main/en.xml"
,就像格伦·惠特尼所做的那样。 //ldml/dates/calendars/calendar[@type="gregorian"]/dateFormats/
查看或下的设置//ldml/dates/calendars/calendar[@type="gregorian"]/timeFormats/
- 下面的参考文献包含有关如何设置字段的文档的链接。 (请注意,下载的 CLDR 文件的格式指定方式与中间语言环境文件的指定方式不同。如果修改 CLDR 文件,请参阅 Unicode LDML 文档。)
- 对 CLDR 文件的某些更改不会传播到中间区域设置文件。 CLDR 文件中的某些项目在 Qt 语言环境框架中没有类似的项目。
- 对于英语语言修改,可以修改
如果编辑中间文件:
- 文件中的每个区域设置大约有 55 行区域设置。
//localeDatabase/localeList/locale/
找到需要修改的相应部分。- 搜索语言或国家/地区以查找要修改的部分。例如,搜索“UnitedStates”并找到与“American English”语言和“United States”国家/地区对应的区域设置块。实际上,搜索“美国”或“美式英语”(两个单词之间有空格)就让我直接找到了我想要修改的块。
- 下面的参考文献包含有关如何设置字段的文档的链接。 (请注意,中间区域设置文件的格式指定方式与下载的 CLDR 文件的格式不同。如果修改中间区域设置文件,请参阅 QtDate 和 QtTime 文档。)
对于大多数用例来说,编辑中间区域设置文件可能更简单。
使用文本编辑器修改
"${CLDRDIR}/common/main"
需要更改的任何文件。如上所述,在此步骤中无需更改任何文件。中间区域设置文件可能更容易编辑。sensible-editor "${CLDRDIR}"/common/main/en.xml
处理 CLDR 文件以制作中间语言环境文件,
localesForQt.xml
文件放置在"${TOPDIR}"
.此步骤将需要几分钟的时间,并且会生成一堆“正在跳过默认内容”和“正在跳过文件”消息。这些消息甚至可能给人留下上一步中修改的文件被跳过的印象。不要恐慌。这些消息似乎具有误导性。"${CLDRScriptsDIR}"/cldr2qlocalexml.py "${CLDRDIR}"/common/main > "${TOPDIR}/localesForQt.xml"
如果需要,可以使用文本编辑器修改或查看中间区域设置文件。如果在生成中间区域设置文件之前对 CLDR 文件进行了更改,则可以检查是否有任何所需的更改已进入中间区域设置文件。
sensible-editor "${TOPDIR}/localesForQt.xml"
一些示例更改(例如,更改为“美国”“美式英语”语言环境):
曾是:
<longDateFormat>dddd, MMMM d, yyyy</longDateFormat> <shortDateFormat>M/d/yy</shortDateFormat> <longTimeFormat>h:mm:ss AP t</longTimeFormat> <shortTimeFormat>h:mm AP</shortTimeFormat>
现在:
<longDateFormat>dddd, MMMM dd, yyyy</longDateFormat> <shortDateFormat>yyyy-MM-dd</shortDateFormat> <longTimeFormat>HH:mm:ss t</longTimeFormat> <shortTimeFormat>HH:mm</shortTimeFormat>
使用提供的脚本从中间语言环境文件生成 C++ 代码。
"${CLDRScriptsDIR}"/qlocalexml2cpp.py "${TOPDIR}/localesForQt.xml" "${QtBaseBuildDIR}"
将修改提交到补丁文件。为补丁命名
"localver_locale_modification.diff"
或类似的名称。将打开一个编辑器,可以在其中记录修改。cd "${QtBaseBuildDIR}" dpkg-source --commit
构建所有 QtBase 库。这一步将需要很长时间。
debuild -us -uc
完成后,上一步将在
"${QtBaseSrcDIR}"
.安装它们dpkg
。请注意,所有软件包的名称中都有“localver”。这对于确定哪些软件包是从源安装的很有用。使用 进行初始安装尝试后dpkg
,如果缺少依赖项,可以使用sudo dpkg --configure -a
和进行修复sudo apt-get -f install
。然后可以重复安装“localver”软件包。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
打开“系统设置”/个性化/区域设置/格式并将区域设置为所需的区域设置(例如“en_US”)。该设置应与区域设置被修改的国家和地区相匹配。单击“详细设置”并在所有子选项中设置相同的区域设置。 (直到我打开并明确设置所有详细设置后,我才获得所有更新。)注销或重新启动以使设置生效。
参考:
kde.org 错误报告: https://bugs.kde.org/show_bug.cgi?id=340982
Unicode 区域设置数据标记语言 (LDML) 第 4 部分:日期 # 日期字段符号表: https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
Qt QTime格式参数: https://doc.qt.io/qt-5/qtime.html#toString
Qt QDate格式参数: https://doc.qt.io/qt-5/qdate.html#fromString
由于链接数量超过允许数量,参考文献被截断。
答案3
一年多后,AFAICT 情况完全相同,我刚刚在 OpenSUSE Tumbleweed 上完成了此过程,以按照我想要的 en_US 方式设置日期格式。下面是分步操作,根据您的喜好替换 [SOMEPATH] (包括括号),如果自我发布此内容以来 CLDR 的版本号从 35.1 升级,您可能需要更新 CLDR 的版本号:
sudo zypper si libqt5-qtbase
# 安装 Qt Core 的源 rpmcd /usr/src/packages/SPECS
sudo rpmbuild -bp libqt5-qtbase.spec
cd [SOMEPATH]
curl http://unicode.org/Public/cldr/35.1/core.zip --output core.zip
unzip core.zip
nano common/main/en.xml
# 或您想要更改的任何语言/区域 - 找到您想要更改的日期格式或本地的任何其他参数,然后根据您的喜好进行编辑。cd /usr/src/packages/BUILD/qtbase-everywhere-src-5.13.0/util/local_database/
./cldr2qlocalexml.py [SOMEPATH]/common/main > [SOMEPATH]/localesForQt.xml
sudo ./qlocalexml2cpp.py [SOMEPATH]/localesForQt.xml /usr/src/packages/BUILD/qtbase-everywhere-src-5.13.0/
cd /usr/src/packages/SPECS
sudo rpmbuild --noprep --noclean -bb libqt5-qtbase.spec
# 去看电影,取决于你的电脑有多快......- 构建完成后,/usr/src/packages/RPMS/[your_architecture] 中应该会创建许多 RPMS。将目录更改为该目录。
sudo zypper install *Core*
- 重新启动并重新登录,您应该会看到您的更改:-)
你看,配置 KDE/Qt 是不是既有趣又方便呢? ;-)