2016-12-17 52 views
1

我在我的项目中使用了HowardHinnant date库。我想在n个月之前得到确切的日期。查找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个月之前的日期。但我无法获得时间。

+0

如果没有这样的日期如'2016-03-31 18:21:26'前一个月? –

+0

@ W.F。 :在这种情况下,它应该返回该月份和年份的最后日期。但是我的功能目前没有处理这种情况。 – Shravan40

回答

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>,或自1970-01-01 UTC以来的秒数。

  • 然后将这个秒数截断为floor<days>()的天数。这是一个std::chrono::time_point<system_clock, days>

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

  • 要做到当月算术,你需要从sys_days(一time_point)切换的sd类型year_month_day(日历类型)。一旦你输入year_month_day,你可以从中减去monthsNum,产生另一个year_month_day(存储在ymd以上)。

  • 您可以检查这是否导致有效日期与.ok()。如果日期无效,则表示您溢出了year_month_day的天数字段。我在评论中看到,如果发生这种情况,您需要每月的最后一天。因此,只需提取yearmonth并使用lastymd重置为该年当月的最后一天。

  • 最后转换ymd回一个sys_daystime_pointdays精度),并添加time_of_day回去吧。

结果是sys_secondstime_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 

Convenience link to documentation.

+0

我在一个答案中看到非常详细的内容后删除了我的答案。除了编程部分外,我还从这个答案中学到了很多东西:) – Shravan40

相关问题