我必须通过从数据库接收的数据来设置Linux上的系统时间--一个整数告诉我们离GMT有多远,一个布尔值启用或禁用DST。
设置禁用DST的时间很容易,Etc/中的文件正是我们所需要的。是否存在启用了DST的类似文件?我想避免将系统时间设置为与特定国家相同,以防他们改变他们的政策-我们希望使时区不受时间限制。
此外,有些时区不可用。有些国家使用WET(GMT 0)及其夏季WEST(GMT+1)或CET(GMT+1)及其CEST(GMT+2),但例如EAT(GMT+3)没有DST等效EAST(GMT+4)。也许没有必要在DST中使用这个特定的时区,但是如果可以独立于国家添加其他时区,那么添加这些时区也应该不难-并且需要添加其他更常见的时区。再次强调,这是为了尽可能地保证时间。也许我们需要定制文件?我们如何建造它们?(this question是相关的,但未回答)
我用C写这个程序,所以如果有任何使用C的替代方案,欢迎使用。记住,我想改变SYSTEM时间,所以除非我误解了它的用法,否则tzset()
是不可能的。
1条答案
按热度按时间qni6mghb1#
我认为您可以通过一组自定义tz文件实现您所说的目标。
tz project是一个有点大和复杂的一个,它可能需要你一些时间来下载它,并学习如何构建它,并学习如何使用你的新的,刚刚构建的区域文件优先于你的系统的默认值。我现在不打算详细讨论所有这些后勤细节。
该项目的源文件之一是
etcetera
,它描述了非地理的纯UTC偏移区域,如GMT+5
。下面是该文件中描述该区域的一行:这意味着我们有一个名为“Etc/GMT+5”的区域,从UTC开始的基本偏移量为-5小时,没有DST转换规则,并且“缩写”为“-05”。(缩写通常是“EDT”或“CEST”之类的东西,它们对于GMT偏移区域特别有问题-不一定有用。
我刚刚对该文件的副本进行了以下更改:
(1)我在末尾添加了两个“规则”行,描述了通用的“3月最后一个星期日和10月最后一个星期日”转换日期:
(2)下面,我开始添加一些GMT偏移区域 * 和 * DST,如下所示:
我没有选择有意义的独特缩写,但关键是我 * 指定了上面定义的新DST转换规则(简称为“DST”)。
然后我重建了zoneinfo文件,将它们放在临时目录“zoneinfo.exp”中:
然后我测试我的新区域说
对我来说,我得到了正确的时间,因为我住在格林威治以西5小时的地区,那里确实观察到了夏令时。我还在去年1月的时间戳上测试了它,当时DST还没有生效,然后也得到了正确的答案。
请注意,这些实际上都不会“改变系统时间”。在Unix和Linux下,系统时间总是UTC。该UTC将根据每个进程的时区转换为本地时间。时区可以由环境变量TZ“临时”设置,或者系统默认值由文件
/etc/localtime
定义,该文件通常是到单个zoneinfo文件之一的符号链接,通常存储在/usr/share/zoneinfo
下的树中。(Note这些zoneinfo文件定义的不仅仅是时区与UTC的偏移量!我们通常会说“我在东部时区,格林威治以西5小时,观察DST”,好像这说明了一切。但是zoneinfo文件不仅记录了DST转换发生的时间,而且还记录了该区域规则更改的整个历史,可以追溯到1970年。这就是为什么可以有多个zoneinfo文件对应于一个看似单一的现代区域的原因:不同的文件描述具有不同历史的区域)。
最后,我不得不说,虽然我在这里描述的似乎是可行的,似乎满足了您的要求,但我不认为这是一个特别好的主意。(UTC offset,Boolean DST flag)的元组 * 不是 * 描述时区的适当方式,因为它未能指定DST转换日期的同等重要的细节。但如果你坚持要这样做,这是实现它的一种方法。