📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

編集の要約なし
4行目: 4行目:


== 本日の経過時刻の取得 ==
== 本日の経過時刻の取得 ==
==== std::chrono ====
==== std::chrono (C++11) ====
本日の0時0分0秒000からの経過時刻 (mS) を求めるには、<code>std::chrono</code> (C++11以降) を使用する。<br>
本日の0時0分0秒000からの経過時刻 (mS) を求めるには、<code>std::chrono</code> (C++11以降) を使用する。<br>
なお、C++17以降およびLinux環境では別の手段も存在する。<br>
なお、C++17以降およびLinux環境では別の手段も存在する。<br>
80行目: 80行目:
  // 指定されたタイムポイントを文字列形式に変換する
  // 指定されたタイムポイントを文字列形式に変換する
  // オフセットを適用してタイムゾーンを調整する
  // オフセットを適用してタイムゾーンを調整する
  std::string format_time(const std::chrono::system_clock::time_point& tp, int offset = 0)
  std::string format_time(const std::chrono::system_clock::time_point &tp, int offset = 0)
  {
  {
     auto time = std::chrono::system_clock::to_time_t(tp) + offset;
     auto time = std::chrono::system_clock::to_time_t(tp) + offset;
93行目: 93行目:
  // 指定されたタイムポイントの日の開始時刻 (00:00:00.000) を計算する
  // 指定されたタイムポイントの日の開始時刻 (00:00:00.000) を計算する
  // タイムゾーンのオフセットも考慮する
  // タイムゾーンのオフセットも考慮する
  std::chrono::system_clock::time_point get_day_start(const std::chrono::system_clock::time_point& tp, int offset = 0)
  std::chrono::system_clock::time_point get_day_start(const std::chrono::system_clock::time_point &tp, int offset = 0)
  {
  {
     auto time = std::chrono::system_clock::to_time_t(tp) + offset;
     auto time = std::chrono::system_clock::to_time_t(tp) + offset;
103行目: 103行目:
   
   
  // 指定されたタイムゾーンの現在時刻と経過時間を表示する
  // 指定されたタイムゾーンの現在時刻と経過時間を表示する
  void print_time_info(const std::string& zone_name, const std::chrono::system_clock::time_point& tp, int offset = 0)
  void print_time_info(const std::string &zone_name, const std::chrono::system_clock::time_point &tp, int offset = 0)
  {
  {
     auto day_start = get_day_start(tp, offset);
     auto day_start = get_day_start(tp, offset);
143行目: 143行目:
<u>より正確な時間を取得する場合は、タイムゾーンライブラリ (例: Howard Hinnant's dateライブラリ等) の使用を推奨する。</u><br>
<u>より正確な時間を取得する場合は、タイムゾーンライブラリ (例: Howard Hinnant's dateライブラリ等) の使用を推奨する。</u><br>
<br>
<br>
C++20では、<code>std::chrono::month</code>や<code>std::chrono::year</code>が追加されるため、月初めからや年頭からの経過時刻 (mS) を取得することができる。<br>
==== std::chrono (C++17) ====
C++17以降では、<code><chrono></code>ライブラリに大幅な拡張が加えられており、タイムゾーンやカレンダーの扱いが簡単になった。<br>
特に、<code>std::chrono::zoned_time</code>クラスの導入により、タイムゾーンを考慮した時間の扱いが可能になった。<br>
 
以下の例では、C++17の新機能を使用して、UTC時間、日本時間、フランス時間の3つのタイムゾーンで現在時刻と本日の経過時間を表示している。<br>
<br>
処理の流れを以下に示す。
# <code>zoned_time</code>クラスを使用して、特定のタイムゾーンでの時間を表現する。
# <code>floor<days></code>を使用して、その日の開始時刻 (午前0時) を計算する。
# <code>duration_cast</code>を使用して、経過時間をミリ秒単位で計算する。
# タイムゾーンは文字列で指定する。 ("UTC", "Asia/Tokyo", "Europe/Paris")<br>これにより、夏時間なども自動的に考慮される。
# タイムゾーンが見つからない場合等はエラーとする。
<br>
<syntaxhighlight lang="c++">
#include <iostream>
#include <chrono>
#include <iomanip>
using namespace std::chrono;
template<typename Clock, typename Duration>
void print_time_info(const std::string &zone_name, const zoned_time<Duration> &zt)
{
    auto now = zt.get_local_time();
    auto today = floor<days>(now);
    auto time_since_midnight = now - today;
    std::cout << zone_name << ":\n";
    std::cout << "  現在時刻: " << now << "\n";
    std::cout << "  経過時間: " << duration_cast<milliseconds>(time_since_midnight).count() << " ms\n\n";
}
int main()
{
    try {
      // 現在のUTC時間を取得
      auto now = system_clock::now();
      // 各タイムゾーンでの時間を計算
      auto utc = zoned_time<milliseconds>("UTC", now);
      auto tokyo = zoned_time<milliseconds>("Asia/Tokyo", now);
      auto paris = zoned_time<milliseconds>("Europe/Paris", now);
      // 各タイムゾーンの情報を表示
      print_time_info("UTC", utc);
      print_time_info("日本時間", tokyo);
      print_time_info("フランス時間", paris);
    }
    catch (const std::exception &e) {
      std::cerr << "エラー: " << e.what() << std::endl;
      return -1;
    }
    return 0;
}
</syntaxhighlight>
<br>
# 出力例
UTC:
  現在時刻: 2024-09-05 05:30:45.123456
  経過時間: 19845123 ms
日本時間:
  現在時刻: 2024-09-05 14:30:45.123456
  経過時間: 52245123 ms
フランス時間:
  現在時刻: 2024-09-05 07:30:45.123456
  経過時間: 27045123 ms
<br>
==== std::chrono (C++20) ====
C++20では、<code>std::chrono::month</code>や<code>std::chrono::year</code>が追加されたため、月初めからや年頭からの経過時刻 (mS) を取得することができる。<br>
また、C++20では、現地時刻用の<code>time_point</code>型、今日の時間情報を取得する<code>time_of_day</code>クラスも追加されるため、<code>time_t</code>型に変換せずに簡単に取得できる。<br>
また、C++20では、現地時刻用の<code>time_point</code>型、今日の時間情報を取得する<code>time_of_day</code>クラスも追加されるため、<code>time_t</code>型に変換せずに簡単に取得できる。<br>
<br>
C++20での主な改善点を以下に示す。<br>
* カレンダーと時間帯のサポートの強化された。
* 日付の操作がより直感的になった。
* 時間帯データベースへのアクセスが改善された。
* 書式化機能が強化されて、日付と時間の出力がより柔軟になった。
<br>
C++20の時間関連機能において、複雑な日付と時間の操作を含むアプリケーションの開発が大幅に簡素化された。<br>
<br>
<syntaxhighlight lang="c++">
#include <iostream>
#include <chrono>
#include <format>
using namespace std::chrono;
template<typename Clock, typename Duration>
void print_time_info(const std::string &zone_name, const zoned_time<Duration> &zt)
{
    auto now = zt.get_local_time();
    auto today = floor<days>(now);
    auto time_since_midnight = now - today;
    auto ymd = year_month_day{today};
    auto time = hh_mm_ss{floor<milliseconds>(time_since_midnight)};
    std::cout << std::format("{}: \n", zone_name);
    std::cout << std::format("  現在時刻: {:%Y-%m-%d %H:%M:%S}.{:03d}\n", now, time.subseconds().count());
    std::cout << std::format("  経過時間: {} ms\n\n", duration_cast<milliseconds>(time_since_midnight).count());
}
int main()
{
    try {
      // 現在のシステム時間を取得
      auto now = system_clock::now();
      // タイムゾーンオブジェクトを取得
      const auto utc = locate_zone("UTC");
      const auto tokyo = locate_zone("Asia/Tokyo");
      const auto paris = locate_zone("Europe/Paris");
      // 各タイムゾーンでの時間を計算
      auto utc_time = zoned_time{utc, now};
      auto tokyo_time = zoned_time{tokyo, now};
      auto paris_time = zoned_time{paris, now};
      // 各タイムゾーンの情報を表示
      print_time_info("UTC", utc_time);
      print_time_info("日本時間", tokyo_time);
      print_time_info("フランス時間", paris_time);
 
      // 日付操作の例
      auto today = floor<days>(utc_time.get_local_time());
      auto this_year = year_month_day{today}.year();
      auto new_years_day = sys_days{this_year/January/1};
      auto days_since_new_year = floor<days>(utc_time.get_sys_time() - new_years_day);
      std::cout << std::format("今年の元旦から今日までの日数: {} 日\n", days_since_new_year.count());
    }
    catch (const std::exception &e) {
      std::cerr << "エラー: " << e.what() << std::endl;
      return -1;
    }
    return 0;
}
</syntaxhighlight>
<br>
# 出力例
UTC:
  現在時刻: 2024-09-05 05:30:45.123
  経過時間: 19845123 ms
日本時間:
  現在時刻: 2024-09-05 14:30:45.123
  経過時間: 52245123 ms
フランス時間:
  現在時刻: 2024-09-05 07:30:45.123
  経過時間: 27045123 ms
今年の元旦から今日までの日数: 249 日
<br>
<u>※注意</u><br>
<u>一部の機能 (特にタイムゾーン関連) は、使用する実装によっては、まだ完全にはサポートされていない可能性がある。</u><br>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:C++]]
[[カテゴリ:C++]]