Introduction

備忘録。
規則的なことだが、すぐに忘れるので。
C# なら System.DateTime というストレート名前があるが、C++ だと面倒なことこの上ない。

How to do?

下記がそのものずばり。
C++ 11。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iomanip>
#include <iostream>
#include <chrono>
#include <ctime>

void output(const std::string header, const std::tm* tm, const uint32_t ms = 0)
{
// struct tm
// {
// int tm_sec; // seconds after the minute - [0, 60] including leap second
// int tm_min; // minutes after the hour - [0, 59]
// int tm_hour; // hours since midnight - [0, 23]
// int tm_mday; // day of the month - [1, 31]
// int tm_mon; // months since January - [0, 11]
// int tm_year; // years since 1900
// int tm_wday; // days since Sunday - [0, 6]
// int tm_yday; // days since January 1 - [0, 365]
// int tm_isdst; // daylight savings time flag
// };

std::cout << header.c_str();
std::cout << tm->tm_year + 1900;
std::cout << "/";
std::cout << std::setfill('0') << std::right << std::setw(2) << tm->tm_mon;
std::cout << "/";
std::cout << std::setfill('0') << std::right << std::setw(2) << tm->tm_mday;
std::cout << " ";
std::cout << std::setfill('0') << std::right << std::setw(2) << tm->tm_hour;
std::cout << ":";
std::cout << std::setfill('0') << std::right << std::setw(2) << tm->tm_min;
std::cout << ":";
std::cout << std::setfill('0') << std::right << std::setw(2) << tm->tm_sec;
std::cout << ".";
std::cout << std::setfill('0') << std::right << std::setw(3) << ms << std::endl;
// or
// std::cout << std::put_time(tm, "%Y/%m/%d %H:%M:%S") << std::endl;
}

int main()
{
// get current time
std::cout << "from time_point" << std::endl;
const std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
const std::time_t time = std::chrono::system_clock::to_time_t(now);

// calendar time (Greenwich Mean Time, GMT)
std::tm* gt = std::gmtime(&time);
output(" gmtime: ", gt);

// calendar time (local time)
std::tm* lt = std::localtime(&time);
output("localtime: ", lt);

std::cout << std::endl;
std::cout << "from Unix Time Stamp millisecond" << std::endl;
const std::chrono::system_clock::duration duration = now.time_since_epoch();
const long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
std::cout << " ms: " << ms << std::endl;

const long long sec = ms / 1000;
gt = std::gmtime(&sec);
output(" gmtime: ", gt, ms % 1000);

lt = std::localtime(&sec);
output("localtime: ", lt, ms % 1000);

return 0;
}

実行結果

1
2
3
4
5
6
7
8
from time_point
gmtime: 2022/10/19 20:38:20.000
localtime: 2022/10/20 05:38:20.000

from Unix Time Stamp millisecond
ms: 1668890300646
gmtime: 2022/10/19 20:38:20.646
localtime: 2022/10/20 05:38:20.646

std::chrono::system_clock::time_point から直接 std::time_t に変換し、UTC あるいはローカル日時に変換する。
または、ミリを Unix エポック (ミリ秒) に変換し、 std::time_t に変換することで UTC あるいはローカル日時に変換することもできる。
後者なら、ミリ秒の値を持っているので、std::time_t が持たないミリ秒の情報を付与できる。