最終更新日時: 2024年12月16日 17時44分52秒 (JST)
yoh が更新

履歴 編集

class
<chrono>

# std::chrono::tai_clock(C++20)

    namespace std::chrono {
      class tai_clock;
    }

## 概要

`tai_clock`は、TAI時間 (国際原子時、International Atomic Time) を表現するためのクロックである。

TAIではうるう秒 (leap second) 補正が行われないため、2017年1月1日以降～2024年現在ではUTC (世界協定時) よりも37秒進んだ時間をとる。 つまり 2024-01-01 00:00:37 TAI と 2024-01-01 00:00:00 UTC は等価である。

このクラスの`now()`静的メンバ関数は、標準では`noexcept(false)`である。実装が`noexcept(true)`である保証をしない限り、このクラスはTrivialClock要件を満たさない。

### エポック

クロックごとの初期時間 (内部的にカウンタがあれば値ゼロ) をエポックと呼ぶ。

`tai_clock`のエポックは、1958年1月1日0時0分0秒である。 これはUTC時間1957年12月31日23時59分50秒に対応する。

### うるう秒の扱い

`tai_clock`ではうるう秒は考慮されず、UTCに対してうるう秒数分だけ時間がシフトする。そのため、UTCに正のうるう秒が挿入されるたびに、UTC時間はTAI時間よりも1秒ずつ遅れていく。

例として、`tai_clock`エポック日 (1958年1月1日) 時点ではUTCには正のうるう秒が10回挿入されており、さらに2000年01月01日までに正のうるう秒が22回、負のうるう秒が0回挿入されたため、2000-01-01 00:00:00 UTCと2000-01-01 00:00:32 TAIは等価となる。

## メンバ関数

### 静的メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`now` | 現在日時を取得する | C++20
`to_utc` | TAI時間からUTC時間へ変換する | C++20
`from_utc` | UTC時間からTAI時間へ変換する | C++20

## メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`rep` | 時間間隔の内部表現となる符号付き算術型。具体的な型は未規定 | C++20
`period` | 時間の周期を表す`ratio`型 `ratio<unspecified, unspecified>` | C++20
`duration` | 時間間隔の型 `duration<rep, period>` | C++20
`time_point` | 時間の一点を指す型 `time_point<utc_clock>` | C++20

## メンバ定数

名前 | 説明 | 対応バージョン
--- | --- | ---
`static constexpr bool is_steady` | 逆行しないクロックかどうかを表す`bool`値。値は未規定。 | C++20

## 例

### 例1: 現在TAI時間

    #include <iostream>
    #include <chrono>

    namespace chrono = std::chrono;

    int main()
    {
      chrono::tai_clock::time_point tp = chrono::tai_clock::now();
      std::cout << tp << std::endl;
    }

#### 出力例

    2019-10-24 11:15:47.519957239

### 例2: うるう秒の影響

    #include <iostream>
    #include <chrono>

    namespace chrono = std::chrono;
    using namespace std::literals::chrono_literals;

    int main() {
      auto utc_tp = chrono::utc_clock::from_sys(chrono::sys_days{2024y/1/1});
      auto tai_tp = chrono::tai_clock::from_utc(utc_tp);
      std::cout << utc_tp << " UTC" << std::endl;
      std::cout << tai_tp << " TAI" << std::endl;
    }

#### 出力

    2024-01-01 00:00:00 UTC
    2024-01-01 00:00:37 TAI

## バージョン

### 言語

- C++20

### 処理系

- Clang: 9.0 ❌
- GCC: 9.2 ❌, 13.2 ✅
- Visual C++: 2019 Update 3 ❌

## 参照

- 国際原子時 - Wikipedia
- 国立天文台 水沢, うるう秒について
- LWG Issue 3359. `<chrono>` leap second support should allow for negative leap seconds