C++日期:两个日期之间的天数 C++(how many days are between)

关于C++日期的问题,在how many days are between中经常遇到, 我看到了 C #,Java 的例子,但对于 C ++ 我找不到解决方案来计算两个日期之间有多少天。

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

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

谢谢

29

这是一种方式。

#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
Here is a ref to Original author post
19

将您的日期转换为表示一个时代以来的天数的整数,然后减去。在这个例子中,我选择了Rata Die,算法的解释可以在 & lt;http://mysite.verizon.net/aesir_research/date/rata.htm& gt;找到。

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);
19

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中,那么它看起来就像:

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 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

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

如果您关注时区,则会在date library的顶部写入一个额外的(单独的)timezone library,以使用IANA timezone database处理时区。如果需要,timezone library还具有用于计算leap seconds的功能。

6

您可以尝试boost date_time

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(943)
Custom writing:为自定义类编写迭代器(circlist)
上一篇
Cemb平衡机:两个Azure虚拟机规模集(VMSS)之间的负载平衡
下一篇

相关推荐

  • cvt和自动挡哪个好提升驾驶体验的最佳选择

    CVT(可变转换器)是一种由传动带及传动轮组成的无级变速器,它可以在没有传动档位的情况下,根据驾驶者的驾驶习惯,自动调整传动轮之间的转速比,从而实现无级变速。自动挡是指车辆自动变速箱,它使用液力传动来实现变速,可以自动适应车辆的行驶状态,减少司机的疲劳,提高行车的舒适性。…

    2023-06-08 07:42:19
    0 93 83
  • cv一叶扁舟和清影轩阳:漫游在一叶扁舟和清影轩阳之间

    cv一叶扁舟是一款开源的计算机视觉库,用于图像处理、计算机视觉等。它提供了丰富的API,可以帮助开发者快速实现各种图像处理任务,如图像分割、目标检测、图像识别等。清影轩阳是一款开源的计算机视觉框架,用于图像处理、目标检测、分类等。它提供了丰富的API,可以帮助开发者快速实现各种图像处理任务,如图像分割、目标检测、图像识别等。…

    2023-08-05 07:06:20
    0 39 84
  • css设置滚动条宽度设置:This is a title

    CSS设置滚动条宽度的方法:使用CSS3的。-webkit-属性:…

    2023-06-06 10:53:01
    0 59 32
  • xl和xe汽车cvt:探索XL和XE汽车的CVT技术优势

    XL和XE汽车CVT是一种变速器,它使用液力变矩器代替传统的机械变速器,以达到更高的效率。它的工作原理是,当发动机输出功率时,液力变矩器就会将这些功率转换为液压能量,然后将能量传递到变速器的输出轴上,从而实现变速。…

    2023-04-09 00:41:04
    0 12 18
  • cordon bleu是什么意思:法式炸鸡卷——Cordon Bleu的经典之作

    Cordon Bleu是一种烹饪技术,其中肉片被置于奶酪和火腿之间,然后用面包屑裹上,最后煎炸或烤熟。这种技术通常用于制作鸡肉,但也可以用于制作其他类型的肉类,如牛肉或猪肉。…

    2024-01-27 15:13:30
    0 39 28
  • countif 非空:非空单元格的计数

    Countif 非空是指计算某个单元格不为空的数量。代码如下:…

    2023-04-22 15:54:15
    0 75 10
  • java double保留一位小数:How to Round a Double to One Decimal Place in

    示例示例使用类可以轻松实现java double保留一位小数的功能,具体代码如下:// 创建对象…

    2023-05-14 07:40:03
    0 29 32
  • linux如何写c语言一个完整的指南

    示例示例在Linux系统中,可以使用C语言编写源代码文件,然后使用GCC编译器来编译源代码文件,生成可执行文件。下面是一个简单的C语言代码示例:…

    2023-05-16 02:02:45
    0 86 53

发表评论

登录 后才能评论

评论列表(3条)