Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manipulate dates/datetimes in c++11?

Tags:

c++

c++11

This is embarrassing, but i am having a hard time doing simple manipulation of datetimes.

This is the c# version of what i basically try to achive using c++11;

DateTime date1=new DateTime(4,5,2012);
DateTime date2=new DateTIme(7,8,2013);
int day1=date1.Days;
TimeSpan ts=d2-d1;
int diffDays=ts.Days;

What did i try?

    std::tm tm;
    tm.tm_year=113;
    tm.tm_mon=0;
    tm.tm_wday=0;

    std::time_t tt=mktime(&tm);
    std::chrono::system_clock::time_point then = std::chrono::system_clock::from_time_t(tt);
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
    auto e1 = std::chrono::duration_cast<std::chrono::hours>(now - then).count();

The value of e1 (379218) makes no sense what so ever.

I took a look at chrono, which is presented as the c++11 standard library for datetime but i just could not find an example of how to create a date having int year=2012, int month=2, int day=14.

PS:Is chrono sufficient for handling date/times/timezones in c++11? Is there a need for time.h?

like image 699
Jack Willson Avatar asked Dec 15 '22 12:12

Jack Willson


1 Answers

New answer for an old question.

Except for messing around with the archaic std::tm, C++11 has no good way of dealing with dates or datetime, with the exception of boost Date Time. And there is one other library that I've been working on lately, that is highly tilted towards performance, compile-time type safety, and chrono compatibility. As presented it only works with C++14, but if you back off some of the constexprs, it will work with C++11. It is header-only, and consists of only one header, and is documented here. It is light on its I/O capability. (and now has extensive I/O capability)

But here is what it looks like for your example:

Oh, now that I look closely, and not knowing C#, I don't know whether DateTime(4,5,2012) refers to Apr 5, 2012, or May 4, 2012. Both m/d/y and d/m/y formats are popularly used. This is one of the problems my library addresses. It accepts both formats unambiguously. For this demo I'm going to assume you are writing in m/d/y format. But I'll use both formats to reproduce your example:

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

int
main()
{
//     DateTime date1=new DateTime(4,5,2012);
//     DateTime date2=new DateTIme(7,8,2013);
//     int day1=date1.Days;
//     TimeSpan ts=d2-d1;
//     int diffDays=ts.Days;

    using namespace date;
    auto date1 = sys_days(apr/5/2012);     // m/d/y is ok
    auto date2 = sys_days(8_d/jul/2013);   // d/m/y is ok
                                           // y/m/d is also ok
    auto diffDays = date2 - date1;         // diffDays is a chrono::duration
    std::cout << diffDays.count() << '\n';
}

This will output:

459

And in C++14, this computation can actually be done at compile time:

constexpr auto date1 = sys_days(apr/5/2012);
constexpr auto date2 = sys_days(8_d/jul/2013);
constexpr auto diffDays = date2 - date1;
static_assert(diffDays == days{459}, "");

And that means that "date constants" can be both very readable and very efficient, compiling down to an "immediate load."

See the documentation for a full description, tutorial and implementation.

like image 191
Howard Hinnant Avatar answered Jan 01 '23 13:01

Howard Hinnant