CTimeSpan.GetDays() 和夏令时

Posted

技术标签:

【中文标题】CTimeSpan.GetDays() 和夏令时【英文标题】:CTimeSpan.GetDays() and daylight savings time 【发布时间】:2010-09-19 14:30:05 【问题描述】:

我在旧的 C++ MFC 程序中发现了一个错误,该程序计算给定日期与固定基准日期的偏移量(以天为单位)。由于某种原因,我们看到结果偏离了一个,我将其追踪到原始程序员使用 CTimeSpan.GetDays() 方法的位置。根据documentation:

请注意,夏令时可能会导致 GetDays 返回一个可能令人惊讶的结果。例如,当 DST 生效时,GetDays 将 4 月 1 日和 5 月 1 日之间的天数报告为 29 天,而不是 30 天,因为 4 月的一天缩短了一个小时,因此不算完整的一天。

我建议的解决方法是改用(obj.GetTotalHours()+1)/24。我认为这将涵盖所有问题,因为这是每天大约在同一时间运行的批处理作业,但我想在实施它之前我会问这里的聪明人是否有更好的方法。

这只是一个附带问题,但我也很好奇如果程序可以随时运行,将如何处理。

【问题讨论】:

【参考方案1】:

只要事件每天在同一时间发生,您的修复方法就可以很好地获取两次之间的整个 24 小时周期数。否则表达式中的“+1”可能会导致非一错误。

有时您并不关心事件发生在一天中的什么时间,您只想知道是哪一天。在这种情况下,您需要将小时、分钟和秒归零,然后使用您的公式:

CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0);
CTime finishDay(finish.GetYear(), finish.GetMonth(), finish.GetDay(), 0, 0, 0);
int days = ((finishDay - startDay).GetTotalHours() + 1) / 24;

【讨论】:

这是有道理的:将时间部分设为 0,然后整数除法将处理夏令时更改时的额外小时【参考方案2】:

对 Mark 建议的内容进行了微小的更改,它无需任何舍入即可工作:只需向 CTime 构造函数添加一个零参数即可。这会强制这两个时间都是标准时间(不是夏令时)。该参数的默认值为 -1,这意味着“如果夏令时生效,则自动计算。”

// Discard hours, minutes, seconds, and daylight savings time
CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0, 0);
CTime endDay(end.GetYear(), end.GetMonth(), end.GetDay(), 0, 0, 0, 0);

// Get number of days apart
CTimeSpan span = endDay - startDay;
int nDays = span.GetDays();

经过测试并且有效。

【讨论】:

以上是关于CTimeSpan.GetDays() 和夏令时的主要内容,如果未能解决你的问题,请参考以下文章

2021年四非信息安全夏令营情况

羽夏逆向——序

羽夏逆向指引——注入

[FAQ] 夏玉米 按规则查询域名靠谱吗 ?

[FAQ] 夏玉米 按规则查询域名靠谱吗 ?

冠夏香氛的崛起:4年年收入过亿是如何实现的