如何在 Linux 环境下设置我自己的夏令时 table?

How to make my own daylight saving time table in Linux environment?

我正在开发一个使用 buildroot 工具构建的 linux 嵌入式项目,我正在使用单声道 运行 我在 linux 系统上的 .net 应用程序。有必要自定义 table 夏令时时间段。用户将在我在 .net 中完成的 GUI 界面中手动插入接下来几年的时间段(夏令时开始和结束时),如果政府更改这些时间段,则允许用户编辑这些时间段。我知道也许还有其他方法可以自动执行此操作,但就像我说的那样,必须有一个用户界面来手动设置或编辑它。

在我使用此文件作为我的区域信息之前:

/usr/share/zoneinfo/America/Sao_Paulo

此文件有圣保罗的夏令时,Linux 启动时会自动更改系统时钟,但我发现我无法编辑此文件,因此它不适用于我。所以我改为:

/usr/share/zoneinfo/Etc/GMT+3

这个文件有我的区域信息,没有夏令时。我打算手动完成。

我做了 GUI 界面,它在 mongodb 数据库中保存了 table 自定义夏令时期间。我的想法是当我检测到当前时间在我的数据库中保存的任何时间段内时,将 linux 系统时钟设置为一小时一小时。它也工作得很好,但问题是当我的 NTP 服务同步和更新系统时钟时,再次将其设置为落后一小时。当然,我不能禁用NTP服务,我也需要这个。

如何实现此功能?在 Linux 中实现此任务更好,还是在我的 .net 应用程序 运行ning on linux 中实现更好?

您可以编写自己替换 localtime(),或者使用 zic 工具

然而,首先:您可能不想这样做。引用@Panagiotis:

The tz database files are updated regularly and distributed automatically. In fact they are the defacto standard.

事实上,"regularly updated" 主要用于历史时区信息,因为时区不会经常更改。在 Buildroot 中,只需安装 tzdata 包,您就拥有了世界上所有的时区。

对于应用时区信息,您总是希望越晚越好。系统时钟必须为UTC。文件上的时间戳也应为 UTC。现代系统记录器(例如 systemd-journald)也以 UTC 格式存储时间戳。所有通过网络通信的时间都应采用 UTC。仅当向用户显示时间时,才需要将其转换为本地时间(不同用户可能有所不同)。

要解决自定义时区的问题,最简单的方法是不使用普通的 localtime()(或任何 .NET 等价物),而是使用首先检查当前时区是否为时区之一的包装函数自定义时区,并在这种情况下进行您自己的时区计算。

或者,您可以生成时区文件并将其写入文件系统。 tzfile format is a binary format, so probably it is easier to generate a text file and convert it with the zic tool。在 Buildroot 中,zic 工具当前不适用于目标,因此您需要更新 package/zic/zic.mk 并添加 package/zic/Config.in。您可以查看 Buildroot 如何从 package/tzdata/tzdata.mk.

中的 tzdata 规则文件生成时区文件

如果您确实需要在系统范围内配置时区(您通常不需要这样做),则必须从 /etc/localtime 创建指向自定义时区的符号链接并将其设置在 /etc/timezone。当然,您必须确保自定义时区文件是可写的。我会建议给你的时区非标准名称,例如从 Custom/ 开始,并使 /usr/share/zoneinfo/Custom 成为可写目录的符号链接。