2016-12-17 5 views
1

私のプロジェクトではHowardHinnant dateライブラリを使用しています。私はnヶ月前に正確なdatetimeを取得したい。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; 
} 

My機能oldDate()nヶ月前だった日付を返します。しかし、私は時間を得ることができません。

+0

をそのような日付などはありません場合はどう'2016-03-31 18:21:26'の1か月前? –

+0

@ W.F。 :そのような場合、その月と年の最終日を返すべきです。しかし、私の機能は現在このケースを扱っていません。 – Shravan40

答えて

2

代わりのcurrentDate()sys_seconds(秒の精度で時間を)返すcurrentTimeを作成:今すぐ

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

oldDateではなくcurrentDatecurrentTimeを呼び出し、そのように時刻を知っていて、保存することができます。

oldDateは、精度が月のstd::chrono::durationであるdate::monthsというパラメータをとる必要があります。ここでは、(その後の記述)のように見えることができるものです:

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は、1日の最初の瞬間(UTC)の時点として考えることができます。したがって、sdtimeから引くと、時刻を表すstd::chrono::durationが得られます。精度は、減​​算している2つの精度のうちcommon_typeになります(seconds)。

  • 月演算を行うには、year_month_daysys_daystime_point)からsdの種類を切り替える(カレンダータイプ)が必要です。 year_month_dayと入力すれば、monthsNumを差し引くだけでyear_month_day(上記のymdに格納されています)を得ることができます。

  • .ok()で有効な日付になったかどうかを確認できます。無効な日付の場合は、year_month_dayの日数フィールドをオーバーフローしたことを意味します。私はコメントで、もしこれが起これば、あなたは月の最終日を望むことを知る。したがって、yearmonthを抽出し、lastを使用して、その年の最後の日にymdをリセットしてください。

  • 最後ymdバックsys_daysdays精度time_point)に変換し、それにtime_of_dayバックを加えます。

結果はsys_secondsseconds精度time_point)です。

私はちょうどこのドライバでこれを実行しました:

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

私は1つの答えで詳しく説明した後、私の答えを削除しました。私はまた、プログラミングの部分以外のこの答えから多くのことを学んだ:) – Shravan40

関連する問題