1
class Solution {
public:
    int daysBetweenDates(string date1, string date2) {
        
    }
};

I have this function. Suppose I have parameter

date1 = "2020-01-15", date2 = "2019-12-31"

How can I find the number of days between these two dates?

JaMiT
  • 14,422
  • 4
  • 15
  • 31
Hoàng
  • 31
  • 2
  • 1
    Please take some time to read or refresh [the help pages](http://stackoverflow.com/help), especially ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also take the [tour] and read about [ask] good questions and [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly learn how to create a [mre] of *your own* attempt, and [edit] your question to show it together with a description of the problems you have. – Some programmer dude Nov 07 '22 at 07:23
  • 1
    If you were given two dates, and asked to work out the number of days between them by hand (e.g. on paper) how would you do it? If you can't describe that, you can't write code to do it either. – Peter Nov 07 '22 at 07:25
  • 1
    Try breaking this assignment into at least two pieces. First, interpret a string as a date (i.e. convert the string into a more convenient form). Second, given two dates in your preferred form, calculate the number of days between them. Hmm... I guess step zero would be to determine what your preferred form for a date is. How do you plan to represent dates internally? – JaMiT Nov 07 '22 at 07:39

2 Answers2

5

Once you parse the date and appropriate month, day, year information is extracted, you can use the <chrono> header to find the difference in days:

// https://godbolt.org/z/hfM8YWze5

#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono;
    auto tp1 = sys_days{January / 15 / 2020};
    auto tp2 = sys_days{December / 31 / 2019};

    std::cout << (tp1 - tp2) << '\n'; // 15d
}

Example:

// https://godbolt.org/z/bo68T5T39

#include <chrono>
#include <iostream>
#include <sstream>
#include <string>

std::chrono::sys_days parse_time(const std::string& time) {
    std::chrono::sys_days days;
    std::istringstream stream{time};
    stream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
    from_stream(stream, "%Y-%2m-%2d", days);
    return days;
}

int main() {
    const auto tp1 = parse_time("2020-01-15");
    const auto tp2 = parse_time("2019-12-31");
    std::cout << (tp1 - tp2) << '\n';  // 15d
}
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • Can you elaborate on the syntax of the brace-initializer for sys_days? Is the `/` an operator overloaded for certain operands like chrono::month? – Peter - Reinstate Monica Nov 07 '22 at 08:52
  • @Peter-ReinstateMonica yes it's overloaded by the chrono library specifically for this purpose. https://en.cppreference.com/w/cpp/chrono/operator_slash – tenfour Nov 07 '22 at 10:05
  • 1
    @tenfour Interesting. Almost too tricky but very useful. (I had googled "std::chrono operator/()" and not found anything (on the first page (-;).) – Peter - Reinstate Monica Nov 07 '22 at 10:11
3

Alternatively, a pre-C++20 solution could be the following:

#include <iostream>
#include <chrono>

int main()
{
    std::string date1 = "2020-01-15";
    std::tm tm1 = {};
    strptime(date1.c_str(), "%Y-%m-%d", &tm1);
    auto tp1 = std::chrono::system_clock::from_time_t(std::mktime(&tm1));
    
    std::string date2 = "2019-12-31";
    std::tm tm2 = {};
    strptime(date2.c_str(), "%Y-%m-%d", &tm2);
    auto tp2 = std::chrono::system_clock::from_time_t(std::mktime(&tm2));
    
    std::chrono::system_clock::duration d = tp1 - tp2;
    using DayLength = std::chrono::duration<int,std::ratio<60*60*24>>;
    DayLength days = std::chrono::duration_cast<DayLength> (d);
    
    std::cout << days.count() << std::endl;

    return 0;
}

I cannot wrap my head enough on how convoluted the date-extraction operation above is, without using C++20 std::chrono::sys_days.

Basically, it makes the following conversions: string -> C string -> struct tm -> time_point -> duration (in periods) -> duration (in days) -> arithmetic type for printing

Giogre
  • 1,444
  • 7
  • 19