2017-03-25 8 views
2

Howard Hinnantの日付C++ライブラリ(https://howardhinnant.github.io/date/date.html)を使用していますが、混乱があります。以下は、2017年11月の第3金曜日の年月日を印刷するためにこのライブラリを使用するプログラムです。date::year_month_weekdayクラスをdate::sys_days()とともに使用すると、正しい日付(2017年11月17日)が表示されますが、 std::chrono::system_clock::to_time_tstruct tmとすると、このtmに格納された結果は2017年11月16日になります。struct tmはいつも1日遅れているようです。私は自分のプログラムで何かを忘れましたか?プログラムは以下の通りですが、コンパイルするにはC++ 11が必要です。mktime()はHoward Hinnantの日付ライブラリ(std :: chronoベース)とは異なる結果を返します

#include <iostream> 
#include <chrono> 
#include <sys/time.h> 
#include "date.h" 

using namespace std; 
using namespace std::chrono; 
using namespace date; 

int main(int argc, char *argv[]) { 
    date::year y(2017); 
    date::month m(11); 
    date::weekday wd((unsigned)5); 
    date::weekday_indexed wi(wd,3); 
    date::year_month_weekday dmwd(y, m, wi); 
    std::cout << date::sys_days(dmwd) << std::endl; //prints 2017-11-17, which is the 3rd Friday of Nov 2017 

    time_t tt = std::chrono::system_clock::to_time_t(date::sys_days(dmwd));   
    struct tm tm1; 
    localtime_r(&tt, &tm1); 
    std::cout << "tm1.tm_year = " << tm1.tm_year << std::endl; 
    std::cout << "tm1.tm_mon = " << tm1.tm_mon << std::endl; 
    std::cout << "tm1.tm_mday = " << tm1.tm_mday << std::endl; //prints 16 instead of 17, one day behind. tm.mday is from 1 to 31. 

    return 0; 
} 

最も実用的な目的のためにUTCである

2017-11-17 
tm1.tm_year = 117 <-- 117+1900=2017 
tm1.tm_mon = 10 <-- tm_mon starts form 0, so 10 means November 
tm1.tm_mday = 16 <-- tm_mday starts from 1, so 16 is the 16-th day in a month 
+1

あなたは '()'の代わりに 'localtime_r()'のgmtime_rを使用してみましたか? –

+0

はい、私はちょうど試みました、 'gmtime_r'は一貫した結果を与えました、ヒントのためにありがとう。 'date :: year_month_weekday'には時間(時分)情報が含まれていないので、' struct tm'に変換するとき、日付ライブラリがその情報をどう扱っているのだろうか。私は 'date :: year_month_weekday'から変換された' struct tm'の 'tm_hour'と' tm_min'も表示します。すべてのケースで、おそらく私がUTC-6タイムゾーンにいるので、 'tm_hour == 18'と' tm_min == 0'と思われますか? –

+0

Fwiw、 'dmwd'を作成する別の構文を次に示します:' auto dmwd = fri [3]/nov/2017; ' –

答えて

2

Howard Hinnant's date.hトラックUnix Timeを次のようにこのプログラムの出力です。これと同じGitHub repositoryには、現地時間やUTC以外の時間帯に対処する必要がある場合は、timezone libraryもあります。

はい、Freddie Chopinがコメントに記したように、localtime_rの影響がコンピュータのローカルタイムゾーンを考慮に入れています。

任意の時刻をsys_daysに追加できます。 sys_daysはですが、精度はdaysです。あなたはsys_daysを持っていたらそう、あなたの代わりに、日付のライブラリで、今<chrono>ライブラリ内で実際にある:

system_clock::time_point t = date::sys_days(dmwd) + 6h + 53min + 4s + 123us: 
+0

ありがとうございます。ちょっと別の質問ですが、 'sys_days(dmwd)'を 'local_days(dmwd)'に変更しようとしましたが、コンパイルされません。 'local_days'を使う正しい方法は何ですか?タイムゾーンライブラリを自分のプログラムにも追加する必要がありますか?再度、感謝します! –

+0

@WorkOnly:私はその実験を試したところ、私のためにコンパイルしました。どのコンパイラ/バージョン?デモをhttps://wandbox.orgのような場所でセットアップできますか?ここから始めるサンドボックスはhttps://wandbox.org/permlink/HMMMIqtuG6Ia1AHYです。 –

+0

私は 'sys_days(dmwd)'を 'local_days(dmwd)'に置き換えたとき、問題なくコンパイルできますが、次のエラーメッセージが表示されます(gcc 5.4、Ubuntu 16.04、 'g ++ -std = 'int main(int、char **)'関数内: date_time.cpp:18:73:エラー: 'std: :chrono :: _ V2 :: system_clock :: to_time_t(date :: local_days) ' time_t tt = std :: chrono :: system_clock :: to_time_t(date :: local_days(dmwd)); ^ ファイル内にdate_timeから含まれています。cpp:2:0: ' –

関連する問題