两个日期之间的天数 C

新手上路,请多包涵

我看到了 C#、Java 的示例,但对于 C++,我找不到计算两个日期之间多少天的解决方案。

例如在 2012-01-24 和 2013-01-08 之间

谢谢!

原文由 Breakdown 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 670
2 个回答

这是一种方式。

 #include <iostream>
#include <ctime>

int main()
{
    struct std::tm a = {0,0,0,24,5,104}; /* June 24, 2004 */
    struct std::tm b = {0,0,0,5,6,104}; /* July 5, 2004 */
    std::time_t x = std::mktime(&a);
    std::time_t y = std::mktime(&b);
    if ( x != (std::time_t)(-1) && y != (std::time_t)(-1) )
    {
        double difference = std::difftime(y, x) / (60 * 60 * 24);
        std::cout << std::ctime(&x);
        std::cout << std::ctime(&y);
        std::cout << "difference = " << difference << " days" << std::endl;
    }
    return 0;
}

我的输出

Thu Jun 24 01:00:00 2004
Mon Jul 05 01:00:00 2004
difference = 11 days

这是原始作者帖子的参考

原文由 sharafjaffri 发布,翻译遵循 CC BY-SA 3.0 许可协议

C++20 更新:

 #include <chrono>
#include <iostream>

int
main()
{
    using namespace std::chrono;
    using namespace std;
    auto x = 2012y/1/24;
    auto y = 2013y/1/8;
    cout << x << '\n';
    cout << y << '\n';
    cout << "difference = " << sys_days{y} - sys_days{x} << 'n';
}

输出:

 2012-01-24
2013-01-08
difference = 350d

如果 {year, month, day} 数据存在于 int s,那么它看起来就像:

 int xy = 2012;
int xm = 1;
int xd = 24;
int yy = 2013;
int ym = 1;
int yd = 8;
auto x = year{xy}/xm/xd;
auto y = year{yy}/ym/yd;
// ...

--- 的类型是 sys_days{y} - sys_days{x}std::chrono::days std::chrono::duration<signed integral type, std::ratio<86'400>> 类型别名。


旧问题的新答案:

使用这个 C++11/C++14 仅标头日期库,您现在可以编写:

 #include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std;
    auto x = 2012_y/1/24;
    auto y = 2013_y/1/8;
    cout << x << '\n';
    cout << y << '\n';
    cout << "difference = " << (sys_days{y} - sys_days{x}).count() << " days\n";
}

哪个输出:

 2012-01-24
2013-01-08
difference = 350 days

如果你不想依赖这个库,你可以编写自己的,使用与上述日期库相同的日期算法。它们可在本文中找到: chrono-Compatible Low-Level Date Algorithms 。本例中使用的本文算法是这样的:

 // Returns number of days since civil 1970-01-01.  Negative values indicate
//    days prior to 1970-01-01.
// Preconditions:  y-m-d represents a date in the civil (Gregorian) calendar
//                 m is in [1, 12]
//                 d is in [1, last_day_of_month(y, m)]
//                 y is "approximately" in
//                   [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
//                 Exact range of validity is:
//                 [civil_from_days(numeric_limits<Int>::min()),
//                  civil_from_days(numeric_limits<Int>::max()-719468)]
template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
    static_assert(std::numeric_limits<unsigned>::digits >= 18,
             "This algorithm has not been ported to a 16 bit unsigned integer");
    static_assert(std::numeric_limits<Int>::digits >= 20,
             "This algorithm has not been ported to a 16 bit signed integer");
    y -= m <= 2;
    const Int era = (y >= 0 ? y : y-399) / 400;
    const unsigned yoe = static_cast<unsigned>(y - era * 400);      // [0, 399]
    const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1;  // [0, 365]
    const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy;         // [0, 146096]
    return era * 146097 + static_cast<Int>(doe) - 719468;
}

有关此算法如何工作、对其进行单元测试及其有效性范围的详细信息,请参阅 chrono-Compatible Low-Level Date Algorithms

该算法对预测的 公历 建模,它无限期地扩展公历,向前和向后。要对其他日历(例如儒略历)建模,您将需要其他算法, 例如此处所示的 算法。一旦你设置了其他日历,并同步到同一个系列纪元(这些算法使用 1970-01-01 Gregorian,这也是 Unix 时间 纪元),你可以很容易地计算出任何两个日期之间的天数,还可以在您建模的任何两个日历之间。

这使您不必在从儒略到公历转换的日期中进行硬编码。您只需要知道您的输入数据是针对哪个日历引用的。

有时,历史文献中可能不明确的日期会用 旧样式/新样式 进行注释,以分别表示儒略历或公历。

如果您还关心日期的时间,这个 相同的日期库<chrono> 库无缝集成以使用 hoursminutes seconds , milliseconds , microseconds and nanoseconds , and with system_clock::now() to get the current date and time.

如果您关心时区,则在 日期库 之上编写了一个额外的(单独的) 时区库,以使用 IANA 时区数据库 处理时区。如果需要, 时区库 还具有计算功能,包括 闰秒

原文由 Howard Hinnant 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题