C++2a で「クリスマスまであと何日」を表示する

こんにちは、yoshiです。
昨年は参加しなかったので2年ぶり2回目のBPSアドベントカレンダー参加です。よろしくおねがいします。
さて、アドベントカレンダーということですから、今年はカレンダーにまつわる話をしてみようかと思います。

時刻を扱うライブラリ <chrono>

C++には、7年前のC++11まで、時間を扱う方法が用意されていませんでした。
もちろんC言語には time_ttm 構造体などがあったので、それを使えば時間を扱うことはできたのですが。
さて、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年のクリスマスにはおそらく発行されていることでしょう。
その頃には、このコードがエラーにならずにちゃんとコンパイルできるかどうかも分かるのではないかと思います。

それでは皆さん、メリー・クリスマス。

関連記事

イマドキの C++erが覚えておくべき便利なWebサービス7選

C++: コンパイル時テストのススメ

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

yoshi

平成元年生まれのC++er。Qiitaで誰が得するのか分からないような重箱の隅をつつく黒魔術を書いていたが、2016年8月からBPSに入社。

yoshiの書いた記事

開発
echoコマンドをC++に移植する

2018年01月18日

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ