gpt4 book ai didi

c++ - 确定夏令时是否适用于特定日期

转载 作者:行者123 更新时间:2023-12-01 19:37:05 28 4
gpt4 key购买 nike

我正在尝试将文件的创建日期修改为发布日期。我首先将诸如“2005年4月2日”之类的字符串转换为std::tm。然后,我创建一个SYSTEMTIME,如下所示:

std::tm dt = from_string("2 April 2005");
SYSTEMTIME st { 0 };
st.wYear = dt.tm_year + 1900; // dt is years from 1900
st.wMonth = dt.tm_mon + 1; // dt is month index 0
st.wDay = dt.tm_mday;
st.wHour = 6; // FILETIME is based on UTC, which is 6 hours ahead

之后,我将 SYSTEMTIME转换为 FILETIME并使用它来应用更改。

这会将文件时间设置为正确的 2 April 2005 12:00:00 AM。但是,将4月2日之后的视频设置为 1:00:00 AM,并且可以肯定的是,夏令时发生在2005年4月3日。

如何确定某个日期是否在夏令时之前或之后,以便可以相应地调整 st.wHour?目标是将所有时间都设置为 12:00:00 AM。优选地,这将在可追溯到60年代的日期以及当前日期起作用。

我尝试使用 TIME_ZONE_INFORMATIONGetTimeZoneInformation,但只得到 TIME_ZONE_ID_STANDARD

最佳答案

一些东西:

  • SYSTEMTIME只是一个简单的结构。它具有年,月,星期几,日(月),小时,分钟,秒和毫秒的单独字段。它既不是UTC时间也不是当地时间,也不是其他时间。除非将其传递给函数,否则不会考虑这一点。
  • FILETIME是另一个简单的结构。它表示自1601-01-01午夜以来的100纳秒间隔数。许多文档会让您以为它始终使用UTC,但是像FileTimeToLocalFileTime这样的函数却不能证明这一点。因此,就像SYSTEMTIME一样,由每个函数决定如何解释它。
  • SystemTimeToFileTime函数接受指向被解释为UTC的SYSTEMTIME的指针,并返回也属于UTC的FILETIME的指针。没有涉及本地时区。
  • 不要自己尝试调整本地时间(代码中的st.wHour = 6)。小时将根据时区和夏令时改变。
  • 除了GetTimeZoneInformation,您没有看到来自TIME_ZONE_STANDARD的任何响应,因为它告诉您当前正在生效的内容-与您可能正在使用的日期断开了连接。
  • 您不应该试图自己弄清楚如何调整DST。 DST并非普遍适用,并且并非总是偏移一小时。而是使用从您关心的时区转换为UTC的函数。

  • 最终,这听起来像是您在询问如何将文件时间设置为特定日期的本地时区的午夜。因此,我建议您执行以下步骤:
  • 构造一个SYSTEMTIME,将您关心的日期和时间分量设置为零(默认值)。
  • 使用 GetDynamicTimeZoneInformation 函数获取本地时区。您希望使用“动态”版本,以便考虑Windows知道的标准时间和DST规则中的任何历史差异,而不仅仅是当前的规则集。
  • 将这两个值传递给 TzSpecificLocalTimeToSystemTimeEx 函数。它将输入时间解释为处于输入时区(这是系统的本地时区)中。结果是按照UTC表示的FILETIME
  • 将该值传递给SetFileTime,后者期望输入的单位是UTC。

  • 另外,请记住 not all file systems track file times in the same way:
  • NTFS存储实际的UTC时间,因此即使计算机具有不同的时区设置,您也可以在计算机之间移动文件,并且时间戳记表示通用时间中的同一点。
  • FAT及其变体存储本地时间。因此,当您调用SetFileTime时,Windows会将UTC转换为本地时区并写入结果。如果然后在具有不同时区的系统上打开文件,则日期将在该时区中解释,从而导致不同的UTC时间。 (将文件从相机移动到计算机时,通常在USB内存棒,存储卡等上看到这种情况。)

  • 最后,您说:

    ... Preferably this would work on dates dating back to the 60s as well as current.



    不幸的是,Windows时区无法跟踪到目前为止的历史日期。 Microsoft's time zone policy将跟踪2010年的时区和DST规则,并转发到地球上所有人口稠密的地方。不过,由于该政策正式制定之前的工件,多个时区跟踪了2010年之前的一些历史变化。 (它们在给定区域内是准确的,只是开始年份在所有区域内都不一致)。

    如果历史日期对您的应用程序很重要,则您将需要一种非常不同的方法-一种不使用Windows时区数据,而使用 IANA time zone database的方法。 (有关更多信息,请参见 the timezone tag wiki。)以下是您可以探索的一些想法:
  • ICU project具有时区支持和C implementation。为此目的,它有点繁重,但是如果您将其用于应用程序的其他本地化方面,则很好。
  • 霍华德·辛南特(Howard Hinnant)(对上述问题发表了评论)在支持IANA时区的情况下具有出色的Date library
  • 可以从 Windows.Globalization.Calendar UWP类获得所需的东西。我尚未测试过是否会使用IANA数据中的历史规则,或者是否会使用Windows数据。 (如果有机会检查,我会回来更新此答案。)

  • 请记住,IANA数据库仅保证从1970年开始。您说过您需要从1960年开始的数据,尽管有一些区域提供了该数据(还有一些更旧的数据),但不能保证该时期的正确性。

    关于c++ - 确定夏令时是否适用于特定日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59699320/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com