首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >两个日期之间的天数C++

两个日期之间的天数C++
EN

Stack Overflow用户
提问于 2013-01-08 23:53:05
回答 3查看 64.6K关注 0票数 22

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

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

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2013-01-09 05:20:14

将日期转换为整数,表示自一个纪元以来的天数,然后减去。在这个例子中,我选择了Rata Die,可以在[http://mysite.verizon.net/aesir\_research/date/rata.htm](http://mysite.verizon.net/aesir_research/date/rata.htm)上找到算法的解释。

int
rdn(int y, int m, int d) { /* Rata Die day one is 0001-01-01 */
    if (m < 3)
        y--, m += 12;
    return 365*y + y/4 - y/100 + y/400 + (153*m - 457)/5 + d - 306;
}

int days = rdn(2013, 1, 8) - rdn(2012, 1, 24);
票数 18
EN

Stack Overflow用户

发布于 2015-08-11 03:54:11

一个老问题的新答案:

使用此C++11/C++14 header-only date library,您现在可以编写:

#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

如果你不想依赖这个库,你可以编写自己的库,使用上面的date库使用的相同的日期算法。它们可以在本文中找到: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

这个算法模拟了proleptic Gregorian calendar,它无限地向前和向后扩展了公历。要对其他日历(如儒略历)建模,您将需要其他算法such as the ones shown here。一旦您设置了其他日历,并将其同步到相同的连续纪元(这些算法使用1970-01-01公历,这也是Unix time纪元),您不仅可以轻松地计算任意两个日期之间的天数,而且还可以计算您建模的任意两个日历之间的天数。

这使您不必在从Julian转换到Gregorian的日期中硬编码。您只需要知道您的输入数据引用的是哪个日历。

有时,历史文档中可能不明确的日期会使用Old Style / New Style进行注释,以分别表示儒略历或公历。

如果您还关心日期的时间,此same date library<chrono>库无缝集成以使用hoursminutessecondsmillisecondsmicrosecondsnanoseconds,并与system_clock::now()无缝集成以获取当前日期和时间。

如果您关心时区,可以在date library之上编写一个额外的(单独的) timezone library,以使用IANA timezone database处理时区。如果需要,timezone library还为包含leap seconds的计算提供了一种工具。

票数 16
EN

Stack Overflow用户

发布于 2013-01-08 23:55:45

您可以尝试使用boost date_time

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14218894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档