I saw examples for C#, Java, but for C++ i cant find solution to calculate how many days between two dates.
For example between 2012-01-24 and 2013-01-08
Thanks!
I saw examples for C#, Java, but for C++ i cant find solution to calculate how many days between two dates.
For example between 2012-01-24 and 2013-01-08
Thanks!
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;
}
Thu Jun 24 01:00:00 2004
Mon Jul 05 01:00:00 2004
difference = 11 days
12:0:0
for the time, not 0:0:0
.) And of course, the order of the elements in the struct tm
aren't specified; you need something like std::tm a; a.tm_year = 104; a.tm_mon = 5; a.tm_mday = 24; a.tm_hour = 12;
. –
Guv August 15, 1979
and June 15, 2018
it gives me 14182
which is 2
days short. The correct number of days are 14184
. I'll try to fix this. –
Cchaddie #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';
}
Output:
2012-01-24
2013-01-08
difference = 350d
If the {year, month, day}
data exists in int
s, then it just looks like:
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;
// ...
The type of sys_days{y} - sys_days{x}
is std::chrono::days
which is a type alias for std::chrono::duration<signed integral type, std::ratio<86'400>>
.
New answer for an old question:
Using this C++11/C++14 header-only date library, you can now write:
#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:
// 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 Algorithms for details about how this algorithm works, unit tests for it, and its range of validity.
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 time epoch), you can easily compute the number of days not only between any two dates, but also between any two calendars which you have modeled.
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.
Sometimes dates in historical documents that might otherwise be ambiguous are annotated with Old Style / New Style to indicate the Julian or Gregorian calendar respectively.
If you are also concerned about the time of day with your dates, this same date library seamlessly integrates with the <chrono>
library for use of hours
, minutes
, seconds
, milliseconds
, microseconds
and nanoseconds
, and with system_clock::now()
to get the current date and time.
If you are concerned about time zones, an additional (separate) timezone library is written on top of the date library to handle time zones using the IANA timezone database. If needed, the timezone library also has a facility for computations that include leap seconds.
std::string
? How would you convert from string
to a type that sys_days()
can use? –
Rosemarierosemary 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>.
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);
(153*m - 457)/5 + d - 306
mean? –
Novel (153 * m - 457)/5
computes the number of preceding days of the shifted month. There are 306 days between March 1 of the year zero and December 31. –
Wakeup To avoid making your own function you can use date_time from Boost.
© 2022 - 2024 — McMap. All rights reserved.
(date1 - date2).to_days();
or even, using C++11 and appropriate code("2012-01-24"_date - "2013-01-08"_date).to_days();
– Heinrike