C++で日付関連の処理についていろいろつまづいたので、忘れないようにまとめておきたいと思います。
tm構造体について
tm構造体はカレンダー日時を保持する構造体です。年月日時分秒などの情報を持ちます。時間を指定をすることで、特定の日時のtm構造体を取得することができます。
tm構造体の2つの注意点
- 1:年の情報が1900年から数えた年である
- tm構造体のtm_yearには年の情報が格納されていますが、これは1900年から数えた年数になっています。 つまり、「2019年」を入れたい場合は「119」を入力する必要があります。
- 2:月の情報が1月から数えた年である
- tm_monには月の情報が格納されていますが、これは1月から数えた月の数になっています。 つまり、11月を指定したい場合には10を入力する必要があります。
//年月の注意点の具体例
int main(void){
//年月の情報をそのまま入力した場合
struct tm badstruct={0,0,0,11,11,2019};
time_t badtime=std::mktime(&badstruct);
//年月の情報を適切に入力した場合
struct tm correctstruct={0,0,0,11,10,2019-1900};
time_t correcttime=std::mktime(&correctstruct);
std::cout << "間違い:" << std::asctime(std::localtime(&badtime)) << std::endl;
std::cout << "正しい:" << std::asctime(std::localtime(&correcttime)) << std::endl;
}

# strtime関数について
strtime関数はtm構造体から必要な情報を選択し、文字列に変換する関数です。この関数を利用することで、構造体の情報を文字列として出力するだけでなく、情報を適切な形に成型して出力することもできます。詳しい変換指定子、出力内容についてはリファレンスを参照してください。
```c++
YYYY/MM/DDの出力例
int main(void){
struct tm timestruct={0,0,0,11,10,2019-1900};
time_t currenttime=std::mktime(×truct);
char str[100];
std::strftime(str, sizeof(str), "%Y/%m/%d", std::localtime(¤ttime));
std::cout << str << std::endl;
}
類似の機能をもった関数としてはasctime関数があり、こちらはtm構造体から特定のテキスト表現(Www Mmm dd hh:mm :ss yyyy\n)に変換します。
参考サイト
・【c++】明日、昨日、指定した日付を取得する
・https://ja.cppreference.com/w/cpp/chrono/c/tm
・https://ja.cppreference.com/w/cpp/chrono/c/time
・https://ja.cppreference.com/w/cpp/chrono/c/asctime