2016-12-17 23 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

相關問題