こんにちは、yoshiです。
昨年は参加しなかったので2年ぶり2回目のBPSアドベントカレンダー参加です。よろしくおねがいします。
さて、アドベントカレンダーということですから、今年はカレンダーにまつわる話をしてみようかと思います。
時刻を扱うライブラリ <chrono>
C++には、7年前のC++11まで、時間を扱う方法が用意されていませんでした。
もちろんC言語には time_t
や tm
構造体などがあったので、それを使えば時間を扱うことはできたのですが。
さて、C++11ではようやく <chrono>
というライブラリが導入されて、時刻を扱うことができるようになりました。
<chrono>
で新たに導入されたのは、
system_clock
steady_clock
high_resolution_clock
といった時計クラスや、
time_point
という時刻の一点を示すクラス、
duration
という時間の差を表すクラスなどでした。
また、 <chrono>
ライブラリにはユーザー定義リテラルが定義されているので、例えば、カップラーメンができるまでの時間を測りたかったら、
using std::literals::chrono_literals;
std::this_thread::sleep_for(3m);
などとすれば3分間スレッドを止めることができます。
しかし、時間を扱う場合、他にも避けては通れない大きなハードルがあります。暦です。
カレンダーを扱う <chrono>
ライブラリの拡張
カレンダーを扱うのは単に時刻を扱うよりも難しいことは、皆さんご存知だと思います。
主に、
- 月あたりの日数にわかりやすい規則がない
- うるう年がある
という二点が特にカレンダーの扱いを難しくしていると私は思います。
独自実装するのは茨の道です。自分でやったらバグを仕込まない自信はありません。
しかし、残念ながら現在のC++にはカレンダーを扱う方法は用意されていません。
ただし、次期規格(C++2aと呼ばれている)で <chrono>
を拡張して標準ライブラリに入ることは内定しています。
そんな訳で、タイトルの通りC++2aで「クリスマスまであと何日」を表示するプログラムを書いて見ようと思います。
なお、この機能はまだ実装が存在しない(Clangでは部分実装されてるが完全ではない)ので、コードの正しさは保証できません。
#include <chrono>
#include <iostream>
int main() {
using namespace std::literals::chrono_literals;
using namespace std::chrono;
auto now = system_clock::now();
std::cout << u8"2020年のクリスマスまであと"
<< ((2020y/December/25d).sys_days() - time_point_cast<days>(now)).count()
<< u8"日です。"
<< std::endl;
}
C++2aは2020年までに発行される予定になっていますので、2020年のクリスマスにはおそらく発行されていることでしょう。
その頃には、このコードがエラーにならずにちゃんとコンパイルできるかどうかも分かるのではないかと思います。
それでは皆さん、メリー・クリスマス。