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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14218894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:07:27  来源:igfitidea点击:

Number of days between two dates C++

c++datedate-arithmetic

提问by Breakdown

I saw examples for C#, Java, but for C++ i cant find solution to calculate how many days between two dates.

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

For example between 2012-01-24 and 2013-01-08

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

Thanks!

谢谢!

回答by sharafjaffri

This is one way.

这是一种方式。

#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;
}

my output

我的输出

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

Here is a ref to Original author post

这是对原始作者帖子的引用

回答by chansen

Convert your dates to integer denoting the number of days since an epoch, then subtract. In this example i chosed Rata Die, an explanation of the algorithm can be found at <http://mysite.verizon.net/aesir_research/date/rata.htm>.

将您的日期转换为表示自一个纪元以来的天数的整数,然后减去。在这个例子中,我选择了Rata Die,该算法的解释可以在 < 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);

回答by Howard Hinnant

New answer for an old question:

旧问题的新答案:

Using this C++11/C++14 header-only date library, you can now write:

使用这个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";
}

Which outputs:

哪些输出:

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

If you don't want to depend on this library, you can write your own, using the same date algorithms that the above date library uses. They are found in this paper: chrono-Compatible Low-Level Date Algorithms. The algorithm from this paper that is being exercised in this example is this one:

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

See chrono-Compatible Low-Level Date Algorithmsfor details about how this algorithm works, unit tests for it, and its range of validity.

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

This algorithm models the proleptic Gregorian calendar, which extends the Gregorian calendar indefinitely, both forwards and backwards. To model other calendars (such as the Julian calendar), you will need other algorithms, such as the ones shown here. Once you have other calendars set up, and synchronized to the same serial epoch (these algorithms use 1970-01-01 Gregorian, which is also the Unix timeepoch), you can easily compute the number of days not only between any two dates, but also between any two calendars which you have modeled.

该算法对预测公历进行建模,该公历将公历无限期地向前和向后扩展。要对其他日历(例如儒略历)进行建模,您将需要其他算法,例如此处显示的算法。一旦您设置了其他日历,并同步到相同的串行纪元(这些算法使用 1970-01-01 格里高利历,这也是Unix 时间纪元),您不仅可以轻松计算任意两个日期之间的天数,也可以在您建模的任何两个日历之间。

This gives you the freedom of not having to hard-code in a date for the switch from Julian to Gregorian. You just have to know which calendar your input data is referenced against.

这使您可以自由地在从 Julian 切换到 Gregorian 的日期中不必进行硬编码。您只需要知道您的输入数据所引用的日历。

Sometimes dates in historical documents that might otherwise be ambiguous are annotated with Old Style / New Styleto indicate the Julian or Gregorian calendar respectively.

有时,历史文件中可能有歧义的日期会用旧样式/新样式注释,以分别指示儒略历或格里高利历。

If you are also concerned about the time of day with your dates, this same date libraryseamlessly integrates with the <chrono>library for use of hours, minutes, seconds, milliseconds, microsecondsand nanoseconds, and with system_clock::now()to get the current date and time.

如果你也关心天与您的日期时间,这同日库无缝集成的<chrono>使用的图书馆hoursminutessecondsmillisecondsmicrosecondsnanoseconds,并与system_clock::now()获得的当前日期和时间。

If you are concerned about time zones, an additional (separate) timezone libraryis written on top of the date libraryto handle time zones using the IANA timezone database. If needed, the timezone libraryalso has a facility for computations that include leap seconds.

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

回答by Howard Hinnant

you can try the boost date_timelibrary

你可以试试boost date_time

回答by Mihai8

To avoid making your own function you can use date_timefrom Boost.

为了避免创建自己的函数,您可以使用Boost 中的date_time