代码之家  ›  专栏  ›  技术社区  ›  Joel Coehoorn

ctimeSpan.getdays()和夏令时

  •  4
  • Joel Coehoorn  · 技术社区  · 16 年前

    我在一个旧的C++ MFC程序中发现了一个错误,我们计算了一个固定日期的给定日期的偏移量(以天为单位)。我们看到的结果由于某种原因被一个关闭了,我跟踪到原始程序员使用ctimespan.getdays()方法的地方。根据 documentation :

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

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

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

    2 回复  |  直到 12 年前
        1
  •  2
  •   Mark Ransom    16 年前

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

    有时你不在乎事件发生在哪一天,你只想知道哪一天。在这种情况下,您需要将小时、分钟和秒归零,然后使用公式:

    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;
    
        2
  •  0
  •   mjk99    12 年前

    对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();
    

    测试和工作。