C# 如何在Linux环境下制作我自己的夏令时表?

C# 如何在Linux环境下制作我自己的夏令时表?,c#,linux,mono,buildroot,C#,Linux,Mono,Buildroot,我正在做一个用buildroot工具构建的linux嵌入式项目,我正在使用mono在linux系统上运行我的.net应用程序。有必要有一个定制的夏令时周期表。用户将在我在.net中完成的GUI界面中手动插入未来几年的时段(夏令时开始和结束时),如果政府更改了这些时段,用户可以编辑这些时段。我知道也许有其他方法可以自动完成,但正如我所说,有必要有一个用户界面来手动设置或编辑它 在将此文件用作我的zoneinfo信息之前: /usr/share/zoneinfo/America/圣保罗 该文件具有圣

我正在做一个用buildroot工具构建的linux嵌入式项目,我正在使用mono在linux系统上运行我的.net应用程序。有必要有一个定制的夏令时周期表。用户将在我在.net中完成的GUI界面中手动插入未来几年的时段(夏令时开始和结束时),如果政府更改了这些时段,用户可以编辑这些时段。我知道也许有其他方法可以自动完成,但正如我所说,有必要有一个用户界面来手动设置或编辑它

在将此文件用作我的zoneinfo信息之前:

/usr/share/zoneinfo/America/圣保罗

该文件具有圣保罗夏时制时间段,Linux在启动时自动更改系统时钟,但我发现我无法编辑该文件,因此它对我不起作用。因此,我改为:

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

此文件包含我的zoneinfo,但没有夏令时。我打算手工做

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


如何实现此功能?在Linux中执行此任务或在Linux上运行的.net应用程序中执行此任务更好吗?

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

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

这些文件定期更新和分发 自动地事实上,它们是事实上的标准

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

对于应用时区信息,您总是希望尽可能晚地执行此操作。系统时钟必须以UTC为单位。文件上的时间戳也应使用UTC。现代系统记录器(如systemd journald)也以UTC格式存储时间戳。通过网络进行通信的所有时间均应为UTC。只有当时间呈现给用户时,才有必要将其转换为本地时间(对于不同的用户可能不同)

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

或者,您可以生成一个时区文件并将其写入文件系统。是一种二进制格式,所以生成文本文件并使用转换可能更容易。在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
作为可写目录的符号链接。

为什么不从zoneinfo文件导入数据?为什么要这样做?这些文件定期更新并自动分发。事实上,它们是事实上的标准。最终用户输入的内容可能来自这些文件的副本,请参阅下面的帖子。Unix日期1是1970年1月1日,而net是1/1/1:如果您有问题,请修复NTP配置或更新tzdata文件。不要试图掩盖这个问题。我可以通过“localZone.GetDaylightChanges(currentYear)”的.NET方法从zoneinfo文件导入数据。但是我认为我不能动态地编辑和保存它。我可以吗?