Search code examples
c++c++-chrono

Subtracting two user input dates C++20 with std::chrono


I'm searching for a method to subtract two dates (ISO 8601 format) which are passed by the user as argument vector. Currently I have this pseudocode:

#include <iostream>
#include <string>
#include <chrono>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <cmath>

int main(int argc, char**argv){

    std::istringstream ssStart{argv[1]};
    std::istringstream ssEnd(argv[2]);

    std::chrono::year_month_day tStart, tEnd;
    ssStart >> std::chrono::parse("%Y-%m-%d", tStart);
    ssEnd >> std::chrono::parse("%Y-%m-%d", tEnd);

    auto tDays = std::chrono::duration_cast<std::chrono::days>(tEnd.day()-tStart.day());
    std::cout << ssStart.str() << "," << ssEnd.str() << "," << tDays.count() << std::endl;

    return 0;
}

Which works if you stay within the same month eg. ./main 2024-01-01 2024-01-31 -> 30, but once you change months ./main 2024-01-01 2024-02-01 the result will be 0. I could sum the diff between year, month and day, but I'm looking for a better solution (I'm skipping error checking for now since this is only a proof of concept).

I've read that year_month_day is not the right structure to use, so please assist me in choosing the correct one.

As stated in the title I use the C++20 standard (g++-14), and no external libraries.


Solution

  • year_month_day is an appropriate type to parse from a string input, but it doesn't support arithmetic. There is however a conversion to std::chrono::sys_days, which is a specialisation of std::chrono::time_point.

    auto tDays = std::chrono::sys_days{ tEnd } - std::chrono::sys_days{ tStart };
    

    tDays is a std::chrono::days value already.