找到n个月前的确切日期和时间?

时间:2016-12-17 12:54:43

标签: c++ datetime c++11 chrono

我在我的项目中使用HowardHinnant date库。我希望在n个月之前得到确切的日期时间。

例如:“2016-12-17 18:21:26”是当前的日期时间,我想知道13个月之前的日期时间。它应输出“2015-11-17 18:21:26”。

/*
 * This function will return the current date in year_month_day format
 */

auto currentDate() {
    auto currentTime = std::chrono::system_clock::now();
    date::year_month_day currentDate = date::floor<date::days>(currentTime);
    return currentDate;
}



/*
 * This function will find the date before (n) months
 */

template <typename T>
auto oldDate(T monthsNum) {
    auto currentDate = currentDate();
    auto yearCurrentDate = (int)currentDate.year();
    auto monthCurrentDate = currentDate.month();
    auto dayCurrentDate = currentDate.day();
    auto yearNum = monthsNum/12;
    auto yearEndDate = yearCurrentDate - yearNum;
    auto monthNum = monthsNum%12;
    auto monthEndDate = monthCurrentDate;
    while(monthNum) {
        monthEndDate--;
    }
    if(monthEndDate > monthCurrentDate) {
        yearEndDate--;
    }
    date::year_month_day endDate = date::year{yearEndDate}/monthEndDate;
    return endDate;
}

我的功能oldDate()将返回n个月之前的日期。但我无法得到时间。

1 个答案:

答案 0 :(得分:2)

而不是currentDate(),创建一个currentTime,返回sys_seconds(精确秒数的时间):

auto
currentTime()
{
    using namespace std::chrono;
    return date::floor<seconds>(system_clock::now());
}

现在oldDate可以致电currentTime而不是currentDate,并以此方式了解并保留时间。

oldDate应将date::months作为参数std::chrono::duration,其精度为月数auto oldDate(date::months monthsNum) { using namespace date; auto time = currentTime(); auto sd = floor<days>(time); auto time_of_day = time - sd; auto ymd = year_month_day{sd} - monthsNum; if (!ymd.ok()) ymd = ymd.year()/ymd.month()/last; return sys_days{ymd} + time_of_day; } 。这是它的样子(后面的描述):

using namespace date

date::非常方便,否则您将在整个地方拥有currentTime()

  • 首先从std::chrono::time_point<system_clock, seconds>获取时间。这是floor<days>(),或自1970-01-01 UTC以来的秒数。

  • 然后使用std::chrono::time_point<system_clock, days>将此秒数截断为天数。这是sd

  • 可以将sd视为当天第一个时刻(以UTC为单位)的时间点。因此,如果您从time中减去std::chrono::duration,则会得到代表时间的common_type。精度将是您减去的两个精度的secondssd)。

  • 要执行月份算术,您需要将sys_days的类型从time_pointyear_month_day)切换为year_month_day(日历类型)。输入monthsNum后,您可以从中减去year_month_day,产生另一个ymd(存储在上面的.ok()中)。

  • 您可以使用year_month_day检查这是否导致了有效日期。如果它是无效日期,则表示您溢出了year的days字段。我在评论中看到,如果发生这种情况,你想要的是该月的最后一天。因此,只需提取monthlast,然后使用ymdymd重置为该年当月的最后一天。

  • 最后将sys_days转换回time_pointdays精度为time_of_day)并将sys_seconds添加回其中。

结果为time_pointseconds,精确度为int main() { using namespace date; std::cout << currentTime() << '\n'; std::cout << oldDate(months{13}) << '\n'; }

我刚用这个驱动程序运行它:

2016-12-17 15:57:52
2015-11-17 15:57:52

输出结果为:

<td > <a href="{% url 'edit' item.id %}" class="confirm" > <img class="autoResizeImage" src="http://www.free-icons-download.net/images/edit-icon-1901.png"/ > </a>  </td>

Convenience link to documentation.