【问题标题】:localtime() gets it wrong, says date = September 31localtime() 弄错了,说日期 = 9 月 31 日
【发布时间】:2012-12-02 09:17:38
【问题描述】:

我正在制作一个日历程序。 “扩展重复事件”代码给我带来了无穷无尽的麻烦。我通过使用 mktime() 来扩展事件以获取“纯”时间值,然后将重复增量(在本例中为 604800 秒或 7 天)添加到它。然后使用 localtime() 来获取日历结构。

发生这种情况:

原始事件:9 月 10 日

{tm_sec = 0, tm_min = 0, tm_hour = 16, tm_mday = 10, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 283, tm_isdst = 0, 
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

第一次重复:9 月 17 日

{tm_sec = 0, tm_min = 0, tm_hour = 17, tm_mday = 17, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 290, tm_isdst = 1, 
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

第二次重复:9 月 24 日

{tm_sec = 0, tm_min = 0, tm_hour = 16, tm_mday = 24, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 297, tm_isdst = 0,
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

第三次重复:9 月 31 日?!

{tm_sec = 0, tm_min = 0, tm_hour = 16, tm_mday = 31, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 304, tm_isdst = 0,
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

有人知道这里发生了什么吗?我需要自己填写localtime()吗?

【问题讨论】:

  • 请记住,tm_year 是自 1900 年以来的年数。所以如果你想要 2012 年(今年),它应该是 112。
  • "...不是编译器错误..."(注意:这次我没有投反对票 - 这是一个容易犯的错误,我敢肯定我也会这样做...)

标签: c datetime mktime localtime


【解决方案1】:

documentationstruct tm 结构的成员是从 0 开始的(通常在 C 中)。

int    tm_mon   month of year [0,11]

所以实际上编号为 9 的月份是第 10 个月,也就是 10 月,它有 31 天。

【讨论】:

  • 即使在 3912 年,这也是 tm_year == 2012 所代表的。顺便说一句,月份数字是从零开始的,因此它们可以用作月份名称数组的索引; tm_mday 是从 1 开始的,因为它没有在索引中使用(我们没有一个月中各天的名称,尽管有“Ides”)。
【解决方案2】:

正如 H2CO3 指出的那样,tm_mon 是从 0 开始的,所以日期实际上是 10 月 31 日,这是有道理的。

我想提一下,简单地将 604800 秒添加到提前 7 天可能不是用户希望从日历程序中获得的。 604800 正好是 7 天,但如果用户希望每 7 天在上午 10:00 重复一次事件,添加 604800 秒并不总是会导致时间为上午 10:00,因为这忽略了特殊注意事项比如夏令时和闰秒。

您可以改为将 7 添加到 tm_mday。不要担心超过一个月的天数,因为mktime() 会更正它。

【讨论】:

  • 感谢您的提示!我不知道 mktime() 会做那种标准化。
猜你喜欢
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多