【问题标题】:How to calculate the number of days between two given dates? (Leap year obstacle)如何计算两个给定日期之间的天数? (闰年障碍)
【发布时间】:2009-09-04 22:40:18
【问题描述】:
  • 任何能被 400 整除的年份都是闰年(例如,2000 年是闰年)。
  • 能被 100 整除的任何其他年份都不是闰年(例如,1700、1800 和 1900 年不是闰年)。
  • 任何其他能被 4 整除的年份都是闰年(例如,1996 年和 2004 年是闰年)。

但我不确定如何在我的 c 程序中创建嵌套的 if 状态以产生正确的答案...

【问题讨论】:

  • 提防古代; 1700 年是英格兰及其殖民地的闰年 - 他们直到 1752 年才采用公历。
  • 听起来像是一个项目欧拉问题 :) 通常日期和日期差异是标准库的一部分 - 因为它既棘手又无聊,没有人应该重新实现它。
  • 另见 metashockwave 的另一个问题:stackoverflow.com/questions/1382124
  • 嘿@metashockwave,如果你不介意,我可以在这里得到一点接受的答案吗?我想要那个愚蠢的徽章。
  • 显然不是。虽然这是一个不错的徽章。我自己也有一个……到处都戴。

标签: c algorithm


【解决方案1】:

将它们都转换为 UNIX 纪元时间并减去差值。

UNIX 纪元时间是自 1970 年 1 月 1 日 00:00:00.0 以来日期的总秒数

获得秒数后,您可以将该差值除以一天中的秒数(24 小时 * 60 分钟 * 60 秒 = 86400 秒)。 p>

【讨论】:

  • 是的,是的,是的。做这个。如果您重视自己的理智,请不要乱用日历。一天的长度是固定的(如果您忽略闰秒,因为软件会这样做)。纪元时间线是一个简单的标量数。这是您想要的表示。任何涉及日历术语的答案都是错误的。
  • 世界大部分地区当地时间的 DST 天数的长度相差一个小时。如果您以秒为单位计算并除以 86400,我会小心舍入,与地板相对。
  • 安迪,当心 2038 年问题等等。而且你也不会得到 1901 年 12 月中旬之前的日期。
  • 而且我的神智不太清醒,所以我在搞日历。
【解决方案2】:

我会转换Julian day 中的两个日期,然后做差异,但我必须先检查这是否是一个没有缺点的好解决方案。我建议你也这样做。

【讨论】:

    【解决方案3】:

    找到一个将日期转换为“自某个纪元以来的天数”的库之一(通常称为儒略日 - 尽管有官方的天文规则 JulianDateModified Julian Date)。然后将每个日期转换为相关数字,并取差。假设图书馆处理闰年,你的答案也是如此。

    有关这样一组代码的想法,请参阅“Calendrical Calculations”。

    【讨论】:

      【解决方案4】:

      Leap year algorithm 来自维基百科:

      伪代码1:

      if year modulo 400 is 0 then leap
       else if year modulo 100 is 0 then no_leap
       else if year modulo 4 is 0 then leap
       else no_leap
      

      伪代码2:

      function isLeapYear (year):
        if ((year modulo 4 is 0) and (year modulo 100 is not 0)) or (year modulo 400 is 0)
         then true
        else false
      

      【讨论】:

        【解决方案5】:
        #include <time.h>
        #define SECONDS_PER_DAY (24 * 60 * 60)
        
        time_t time_from_date(int year, unsigned month, unsigned day)
        {
            return mktime(&(struct tm){
                .tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day });
        }
        
        int days_between(int year0, unsigned month0, unsigned day0,
            int year1, unsigned month1, unsigned day1)
        {
            return difftime(time_from_date(year1, month1, day1),
                time_from_date(year0, month0, day0)) / SECONDS_PER_DAY;
        }
        

        【讨论】:

        • @Stefano:是的,因为我使用了带有命名初始化程序的复合文字作为mktime() 的参数;对于 C90 版本,在函数中声明结构并单独设置成员
        【解决方案6】:

        您根本不需要嵌套条件。

        提示:与其尝试确定给定年份是否为闰年,不如尝试确定其之前的闰日总数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-13
          • 1970-01-01
          • 2018-11-18
          • 1970-01-01
          • 2010-09-14
          相关资源
          最近更新 更多