给定日期和今天日期之间的C ++天数

时间:2015-11-14 19:56:20

标签: c++ date c++11 boost time

我有一个名为int differenceDatesInDays(string& date)的函数。 这个函数应该得到一个字符串值作为日期(YYYY-MM-DD)并将其与今天的日期进行比较。

我不知道STL中是否有东西,我找不到匹配的算法。我刚刚发现boost有一个解决方案,但我不想使用boost。

所以,到目前为止,这是我的代码:

int differenceDatesInDays(string& date) {
    string year = date.substr(0, 4);
    string month = date.substr(5,2);
    string day = date.substr(8, string::npos);

    int y = stoi(year);
    int m = stoi(month);
    int d = stoi(day);

    time_t time_now = time(0);
    tm* now = localtime(&time_now);

    int diffY = y - (now->tm_year + 1900);
    int diffM = m - (now->tm_mon + 1);
    int diffD = d - (now->tm_mday);

    int difference = (diffY * 365) + (diffM * 30) + diffD;

    return difference;
}

我不知道如何查明这个月是30天,31天还是28天。

3 个答案:

答案 0 :(得分:5)

一旦你有两个完整的三元组:{y1, m1, d1}{y0, m0, d0},计算它们之间差异的最有效方法是使用公共域函数days_from_civil来计算序列日计数每个三元组,并减去它们:

diff = days_from_civil(y1, m1, d1) - days_from_civil(y0, m0, d0);

重复days_from_civil

// 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;
}

这比基于tm的典型代码具有更大的有效范围。它会更快。而且你不会被迫处理时间。如果您的所有信息都是编译时常量,并且您使用的是C ++ 14,那么您可以在编译时获得答案。

答案 1 :(得分:4)

由于您使用Boost标记了它,为什么不使用它并免费获取所有内容:

<强> Live On Coliru

#include <boost/date_time/gregorian/gregorian.hpp>

int differenceDatesInDays(std::string const& s) {
    using namespace boost::gregorian;
    return (day_clock::local_day() - from_string(s)).days();
}

int main() {
    return differenceDatesInDays("2015-01-01");
}

打印

317

答案 2 :(得分:2)

这些方面的一些东西,也许是:

int differenceDatesInDays(string& date) {
    // Parse `date` as in your code
    int y = ...;
    int m = ...;
    int d = ...;

    tm then = {0};
    then.tm_year = y - 1900;
    then.tm_mon = m - 1;
    then.tm_day = d;
    time_t then_secs = mktime(&then);

    time_t time_now = time(0);
    tm* now = localtime(&time_now);
    tm today = {0};
    today.tm_year = now->tm_year;
    today.tm_mon = now->tm_mon;
    today.tm_day = now->tm_day;
    time_t today_secs = mktime(&today);

    return (today_secs - then_secs) / (24*60*60);
}