13#if __cplusplus >= 202002L
20#if __cplusplus >= 202002L
22 using time_point = std::chrono::time_point<std::chrono::system_clock>;
25 inline const std::chrono::time_zone *TIME_ZONE
26 = std::chrono::current_zone();
28 template<
typename char_t,
typename int_t>
30 std::basic_ostream<char_t> &sOutput,
32 const std::uint8_t nMinCiphers
34 static_assert(std::is_integral_v<int_t>);
38 for (std::uint8_t i = 1; i < nMinCiphers; ++i) {
39 sOutput.put(
static_cast<char_t
>(
'0'));
46 if constexpr (std::is_signed_v<int_t>) {
48 sOutput.put(
static_cast<char_t
>(
'-'));
54 auto nValueCopy = nValue / 10;
59 while (nValueCopy > 0) {
66 if (nDigits < nMinCiphers) {
67 for (std::uint8_t i = nDigits; i < nMinCiphers; ++i) {
68 sOutput.put(
static_cast<char_t
>(
'0'));
75 auto nCipher = nValue / nExp +
'0';
76 sOutput.put(
static_cast<char_t
>(nCipher));
84 template<
typename char_t>
85 void toRfc3339Utc(std::basic_ostream<char_t> &sOutput,
const time_point nTime) {
87 const auto nDays = std::chrono::floor<std::chrono::days>(nTime);
88 const std::chrono::year_month_day nDate{nDays};
89 const auto nInstantMillis = std::chrono::floor<std::chrono::milliseconds>(nTime - nDays);
90 const std::chrono::hh_mm_ss nInstant{nInstantMillis};
93 const int nYears =
static_cast<int>(nDate.year());
94 const unsigned nMonth =
static_cast<unsigned>(nDate.month());
95 const unsigned nDay =
static_cast<unsigned>(nDate.day());
96 const unsigned nHour = nInstant.hours().count();
97 const unsigned nMinute = nInstant.minutes().count();
98 const unsigned nSecond = nInstant.seconds().count();
99 const unsigned nMillis = nInstant.subseconds().count();
102 writeInteger<char_t, int>(sOutput, nYears, 4);
103 sOutput.put(
static_cast<char_t
>(
'-'));
104 writeInteger<char_t, unsigned>(sOutput, nMonth, 2);
105 sOutput.put(
static_cast<char_t
>(
'-'));
106 writeInteger<char_t, unsigned>(sOutput, nDay, 2);
107 sOutput.put(
static_cast<char_t
>(
' '));
110 writeInteger<char_t, unsigned>(sOutput, nHour, 2);
111 sOutput.put(
static_cast<char_t
>(
':'));
112 writeInteger<char_t, unsigned>(sOutput, nMinute, 2);
113 sOutput.put(
static_cast<char_t
>(
':'));
114 writeInteger<char_t, unsigned>(sOutput, nSecond, 2);
115 sOutput.put(
static_cast<char_t
>(
'.'));
116 writeInteger<char_t, unsigned>(sOutput, nMillis, 3);
117 sOutput.put(
static_cast<char_t
>(
'Z'));
120 template<
typename char_t>
121 void toRfc3339Local(std::basic_ostream<char_t> &sOutput,
const time_point nTime) {
123 const auto pZone = TIME_ZONE;
124 const auto oZoneInfo = pZone->get_info(nTime);
125 const auto nLocalTime = pZone->to_local(nTime);
128 const auto nDays = std::chrono::floor<std::chrono::days>(nLocalTime);
129 const std::chrono::year_month_day nDate{nDays};
130 const auto nInstantMillis = std::chrono::floor<std::chrono::milliseconds>(nLocalTime - nDays);
131 const std::chrono::hh_mm_ss nInstant{nInstantMillis};
134 const int nYears =
static_cast<int>(nDate.year());
135 const unsigned nMonth =
static_cast<unsigned>(nDate.month());
136 const unsigned nDay =
static_cast<unsigned>(nDate.day());
137 const unsigned nHour = nInstant.hours().count();
138 const unsigned nMinute = nInstant.minutes().count();
139 const unsigned nSecond = nInstant.seconds().count();
140 const unsigned nMillis = nInstant.subseconds().count();
143 writeInteger<char_t, int>(sOutput, nYears, 4);
144 sOutput.put(
static_cast<char_t
>(
'-'));
145 writeInteger<char_t, unsigned>(sOutput, nMonth, 2);
146 sOutput.put(
static_cast<char_t
>(
'-'));
147 writeInteger<char_t, unsigned>(sOutput, nDay, 2);
148 sOutput.put(
static_cast<char_t
>(
' '));
151 writeInteger<char_t, unsigned>(sOutput, nHour, 2);
152 sOutput.put(
static_cast<char_t
>(
':'));
153 writeInteger<char_t, unsigned>(sOutput, nMinute, 2);
154 sOutput.put(
static_cast<char_t
>(
':'));
155 writeInteger<char_t, unsigned>(sOutput, nSecond, 2);
156 sOutput.put(
static_cast<char_t
>(
'.'));
157 writeInteger<char_t, unsigned>(sOutput, nMillis, 3);
160 auto nOffsetSecs = oZoneInfo.offset.count();
161 if (nOffsetSecs >= 0) {
162 sOutput.put(
static_cast<char_t
>(
'+'));
164 sOutput.put(
static_cast<char_t
>(
'-'));
165 nOffsetSecs = -nOffsetSecs;
169 const auto nOffsetTotalMinutes =
static_cast<unsigned>(nOffsetSecs / 60);
170 const unsigned nOffsetHours = nOffsetTotalMinutes / 60;
171 const unsigned nOffsetMins = nOffsetTotalMinutes % 60;
174 writeInteger<char_t, int>(sOutput,
static_cast<unsigned>(nOffsetHours), 2);
175 sOutput.put(
static_cast<char_t
>(
':'));
176 writeInteger<char_t, int>(sOutput,
static_cast<unsigned>(nOffsetMins), 2);
179 template<
typename char_t>
181 std::basic_ostream<char_t> &sOutput,
185 auto nTime = std::chrono::system_clock::now();
187 Detail::toRfc3339Local<char_t>(sOutput, nTime);
189 Detail::toRfc3339Utc<char_t>(sOutput, nTime);
190 sOutput.put(
static_cast<char_t
>(
' '));
Root namespace for the CppTrail logging library.
Definition async_logger.h:24
Internal implementation details. Not intended for direct public use.