メモの日々


2023年08月24日(木) [長年日記]

[c++] std::chrono::time_pointの文字列表現から秒未満を除去する

system_clockから取得する現在時刻を文字列として出力すると秒未満の値も出力されるが、秒未満の値を出力しないようにするにはどうするのか。

std::cout << std::chrono::system_clock::now() << std::endl;
2023-08-23 15:41:17.7805038

std::put_time() でできる

<iomanip>にあるput_time()を使うと一応できる。でも gmtime とか呼びたくない。

#include <chrono>
#include <iomanip>
#include <iostream>
#include <time.h>

int main()
{
    namespace ch = std::chrono;

    const auto now = ch::system_clock::now();
    const auto now_t = ch::system_clock::to_time_t(now);
    tm tm;
    gmtime_s(&tm, &now_t);
    std::cout << std::put_time(&tm, "%F %T") << std::endl;
}
2023-08-23 15:43:08

std::format() でできない

format()でフォーマット指定することで制御できそうなものだが、秒だけを出力する指定子は無いみたい。put_time()とは「%T」(というか「%S」)の挙動が違う。

time_pointのdurationを変更するとできる

time_pointの刻みを粗くして、秒単位の時刻に変換すれば秒未満の値は出力されなくなる。釈然としないが、これが想定されている制御方法のようだ。

#include <chrono>
#include <iostream>

int main()
{
    namespace ch = std::chrono;

    const auto now = ch::system_clock::now();
    const auto now2 = ch::floor<ch::seconds>(now);

    std::cout << now << std::endl;
    std::cout << std::format("{:%F %T}", now) << std::endl;
    std::cout << now2 << std::endl;
    std::cout << std::format("{:%F %T}", now2) << std::endl;
}
2023-08-23 15:43:36.5353184
2023-08-23 15:43:36.5353184
2023-08-23 15:43:36
2023-08-23 15:43:36