3#ifndef _TIME_SHIELD_TIME_FORMATTING_HPP_INCLUDED
4#define _TIME_SHIELD_TIME_FORMATTING_HPP_INCLUDED
32 std::string& result) {
35 if (repeat_count > 1)
break;
39 if (repeat_count > 1)
break;
43 if (repeat_count == 1) {
46 result += std::string(buffer);
50 if (repeat_count <= 2) {
52 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
hour);
53 result += std::string(buffer);
57 if (repeat_count == 2) {
59 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
hour);
60 result += std::string(buffer);
67 if (repeat_count > 1)
break;
68 result +=
to_str(
static_cast<Month>(dt.
mon), FormatType::SHORT_NAME);
71 if (repeat_count > 1)
break;
72 result +=
to_str(
static_cast<Month>(dt.
mon), FormatType::FULL_NAME);
77 if (repeat_count <= 1){
81 result +=
to_str(
static_cast<Month>(dt.
mon), FormatType::SHORT_NAME);
84 std::fill(buffer, buffer +
sizeof(buffer),
'\0');
85 snprintf(buffer,
sizeof(buffer),
"%2d ", dt.
day);
86 result += std::string(buffer);
88 std::fill(buffer, buffer +
sizeof(buffer),
'\0');
89 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2d ", dt.
hour, dt.
min, dt.
sec);
90 result += std::string(buffer);
92 result += std::to_string(dt.
year);
96 if (repeat_count > 1)
break;
97 result += std::to_string(dt.
year/100);
100 if (repeat_count < 2) {
101 char buffer[4] = {0};
102 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
day);
103 result += std::string(buffer);
107 if (repeat_count == 1) {
109 char buffer[16] = {0};
110 snprintf(buffer,
sizeof(buffer),
"%.2d/%.2d/%.2d", dt.
mon, dt.
day, (
int)(dt.
year % 100LL));
111 result += std::string(buffer);
113 if (repeat_count == 2) {
114 char buffer[4] = {0};
115 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
day);
116 result += std::string(buffer);
120 if (repeat_count == 1) {
121 char buffer[4] = {0};
122 snprintf(buffer,
sizeof(buffer),
"%2d", dt.
day);
123 result += std::string(buffer);
131 if (repeat_count == 1) {
133 char buffer[32] = {0};
134 if (dt.
year <= 9999 && dt.
year >= 0) {
135 snprintf(buffer,
sizeof(buffer),
"%.4d-%.2d-%.2d", (
int)dt.
year, dt.
mon, dt.
day);
138 snprintf(buffer,
sizeof(buffer),
"-%" PRId64
"-%.2d-%.2d", dt.
year, dt.
mon, dt.
day);
140 snprintf(buffer,
sizeof(buffer),
"+%" PRId64
"-%.2d-%.2d", dt.
year, dt.
mon, dt.
day);
142 result += std::string(buffer);
147 if (repeat_count == 1) {
149 const int two_digit_year =
static_cast<int>(iso_week.
year % 100);
150 char buffer[4] = {0};
151 snprintf(buffer,
sizeof(buffer),
"%.2d", two_digit_year < 0 ? -two_digit_year : two_digit_year);
152 result += std::string(buffer);
157 if (repeat_count == 1) {
159 result += std::to_string(iso_week.
year);
163 if (repeat_count == 1) {
164 char buffer[4] = {0};
166 result += std::string(buffer);
170 if (repeat_count == 1) {
171 char buffer[4] = {0};
172 snprintf(buffer,
sizeof(buffer),
"%2d", dt.
hour);
173 result += std::string(buffer);
177 if (repeat_count == 1) {
178 char buffer[4] = {0};
180 result += std::string(buffer);
184 if (repeat_count == 1) {
185 char buffer[4] = {0};
186 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
mon);
187 result += std::string(buffer);
189 if (repeat_count == 2) {
190 char buffer[4] = {0};
191 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
min);
192 result += std::string(buffer);
196 if (repeat_count == 1) {
197 char buffer[4] = {0};
198 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
min);
199 result += std::string(buffer);
201 if (repeat_count == 2) {
202 char buffer[4] = {0};
203 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
mon);
204 result += std::string(buffer);
206 if (repeat_count == 3) {
207 result +=
to_str(
static_cast<Month>(dt.
mon), FormatType::UPPERCASE_NAME);
217 if (dt.
hour < 12) result +=
"AM";
221 if (dt.
hour < 12) result +=
"am";
225 if (repeat_count == 1) {
226 char buffer[16] = {0};
229 result += std::string(buffer);
235 if (repeat_count == 1) {
236 char buffer[8] = {0};
237 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d", dt.
hour, dt.
min);
238 result += std::string(buffer);
242 if (repeat_count == 1) {
243 result += std::to_string(
ts);
246 if (repeat_count == 3) {
247 result += std::to_string(dt.
ms);
254 if (repeat_count <= 2) {
255 char buffer[4] = {0};
256 snprintf(buffer,
sizeof(buffer),
"%.2d", dt.
sec);
257 result += std::string(buffer);
259 if (repeat_count == 3) {
260 result += std::to_string(dt.
ms);
265 if (repeat_count > 1)
break;
270 if (repeat_count == 1) {
271 char buffer[16] = {0};
272 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2d", dt.
hour, dt.
min, dt.
sec);
273 result += std::string(buffer);
277 if (repeat_count == 1) {
281 result += std::to_string(dw);
289 if (repeat_count == 1) {
291 char buffer[4] = {0};
292 snprintf(buffer,
sizeof(buffer),
"%.2d", iso_week.
week);
293 result += std::string(buffer);
298 if (repeat_count == 1) {
301 if (repeat_count == 3) {
307 if (repeat_count == 3) {
318 if (repeat_count == 1) {
319 result += std::to_string(dt.
year % 100);
323 if (repeat_count == 1) {
324 result += std::to_string(dt.
year);
326 if (repeat_count == 6) {
327 char buffer[32] = {0};
328 const int64_t mega_years = dt.
year / 1000000;
329 const int64_t millennia = (dt.
year - mega_years * 1000000) / 1000;
330 const int64_t centuries = dt.
year - mega_years * 1000000 - millennia * 1000;
336 "%" PRId64
"M%" PRId64
"K%.3" PRId64,
338 static_cast<int64_t
>(std::abs(millennia)),
339 static_cast<int64_t
>(std::abs(centuries)));
344 "%" PRId64
"M%.3" PRId64,
346 static_cast<int64_t
>(std::abs(centuries)));
353 "%" PRId64
"K%.3" PRId64,
355 static_cast<int64_t
>(std::abs(centuries)));
357 snprintf(buffer,
sizeof(buffer),
"%.4" PRId64, dt.
year);
359 result += std::string(buffer);
361 if (repeat_count == 4) {
362 char buffer[8] = {0};
363 snprintf(buffer,
sizeof(buffer),
"%.4d", (
int)(dt.
year % 10000));
364 result += std::string(buffer);
366 if (repeat_count == 2) {
367 char buffer[8] = {0};
368 snprintf(buffer,
sizeof(buffer),
"%.2d", (
int)(dt.
year % 100));
369 result += std::string(buffer);
374 if (repeat_count == 1) {
376 char buffer[16] = {0};
378 else snprintf(buffer,
sizeof(buffer),
"-%.2d%.2d", tz.
hour, tz.
min);
379 result += std::string(buffer);
424 template<
class T = ts_t>
426 const std::string& format_str,
428 tz_t utc_offset = 0) {
430 if (format_str.empty())
return result;
431 const T local_timestamp =
static_cast<T
>(
timestamp +
static_cast<T
>(utc_offset));
434 bool is_command =
false;
435 size_t repeat_count = 0;
436 char last_char = format_str[0];
437 if (last_char !=
'%') result += last_char;
438 for (
size_t i = 0; i < format_str.size(); ++i) {
439 const char& current_char = format_str[i];
441 if (current_char ==
'%') {
443 if (repeat_count == 2) {
444 result += current_char;
450 result += current_char;
453 last_char = current_char;
457 if (last_char == current_char) {
474 template<
class T = ts_t>
476 const std::string& format_str,
478 tz_t utc_offset = 0) {
508 template<
class T = ts_ms_t>
510 const std::string& format_str,
512 tz_t utc_offset = 0) {
514 if (format_str.empty())
return result;
518 bool is_command =
false;
519 size_t repeat_count = 0;
520 char last_char = format_str[0];
521 if (last_char !=
'%') result += last_char;
522 for (
size_t i = 0; i < format_str.size(); ++i) {
523 const char& current_char = format_str[i];
525 if (current_char ==
'%') {
527 if (repeat_count == 2) {
528 result += current_char;
534 result += current_char;
537 last_char = current_char;
541 if (last_char == current_char) {
558 template<
class T = ts_t>
560 const std::string& format_str,
562 tz_t utc_offset = 0) {
573 template<
class T = ts_t>
576 char buffer[32] = {0};
577 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
581 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d",
593 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d",
601 return std::string(buffer);
611 template<
class T = ts_t>
614 char buffer[32] = {0};
618 "%" PRId64
"-%.2d-%.2d",
622 return std::string(buffer);
632 template<
class T = ts_t>
635 char buffer[32] = {0};
636 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
637 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2d.%.3d", dt.
hour, dt.
min, dt.
sec, dt.
ms);
639 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2d", dt.
hour, dt.
min, dt.
sec);
641 return std::string(buffer);
651 template<
class T = ts_t>
654 char buffer[32] = {0};
655 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
656 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2d.%.3dZ", dt.
hour, dt.
min, dt.
sec, dt.
ms);
658 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2dZ", dt.
hour, dt.
min, dt.
sec);
660 return std::string(buffer);
670 template<
class T = ts_t>
673 char buffer[32] = {0};
674 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
678 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
690 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2dZ",
698 return std::string(buffer);
709 char buffer[32] = {0};
713 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
721 return std::string(buffer);
732 char buffer[32] = {0};
736 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d",
744 return std::string(buffer);
755 template<
class T = ts_t>
758 const T local_ts =
static_cast<T
>(
ts +
static_cast<T
>(utc_offset));
760 char buffer[32] = {0};
761 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
766 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d+%.2d:%.2d",
780 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d-%.2d:%.2d",
796 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d+%.2d:%.2d",
809 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d-%.2d:%.2d",
820 return std::string(buffer);
834 char buffer[32] = {0};
839 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d+%.2d:%.2d",
853 "%" PRId64
"-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d-%.2d:%.2d",
864 return std::string(buffer);
875 char buffer[32] = {0};
879 "%" PRId64
".%.2d.%.2d %.2d:%.2d:%.2d",
886 return std::string(buffer);
903 char buffer[32] = {0};
907 "%" PRId64
".%.2d.%.2d",
911 return std::string(buffer);
922 char buffer[32] = {0};
923 snprintf(buffer,
sizeof(buffer),
"%.2d:%.2d:%.2d", dt.
hour, dt.
min, dt.
sec);
924 return std::string(buffer);
932 char buffer[32] = {0};
936 "%" PRId64
"-%.2d-%.2d_%.2d-%.2d-%.2d",
943 return std::string(buffer);
951 char buffer[32] = {0};
955 "%" PRId64
"-%.2d-%.2d_%.2d-%.2d-%.2d-%.3d",
963 return std::string(buffer);
971 char buffer[32] = {0};
975 "%" PRId64
"-%.2d-%.2d %.2d:%.2d:%.2d",
982 return std::string(buffer);
990 char buffer[32] = {0};
994 "%" PRId64
"-%.2d-%.2d %.2d:%.2d:%.2d.%.3d",
1002 return std::string(buffer);
Configuration macros for the library.
Header for date and time structure and related functions.
TIME_SHIELD_CONSTEXPR ts_t timestamp(year_t year, int month, int day)
Alias for to_timestamp.
TIME_SHIELD_CONSTEXPR ts_t ts(year_t year, int month, int day)
Alias for to_timestamp.
IsoWeekDateStruct to_iso_week_date(Y year, M month, D day)
Convert calendar date to ISO week date.
TIME_SHIELD_CONSTEXPR T hour24_to_12(T hour) noexcept
Converts a 24-hour format hour to a 12-hour format.
T to_time_zone(tz_t offset)
Converts an integer to a time zone structure.
TIME_SHIELD_CONSTEXPR ts_ms_t ts_ms(year_t year, int month, int day)
Alias for to_timestamp_ms.
TIME_SHIELD_CONSTEXPR T1 day_of_week(year_t year, int month, int day)
Alias for day_of_week_date.
TIME_SHIELD_CONSTEXPR T1 sec_to_ms(T2 ts) noexcept
Converts a timestamp from seconds to milliseconds.
const std::string & to_str(Weekday value, FormatType format=UPPERCASE_NAME)
Converts a Weekday enum value to a string.
TimeZoneStruct to_time_zone_struct(tz_t offset)
Converts an integer to a TimeZoneStruct.
T to_date_time_ms(ts_ms_t ts)
Converts a timestamp in milliseconds to a date-time structure with milliseconds.
T day_of_year(ts_t ts=time_shield::ts())
Get the day of the year.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
int64_t ts_t
Unix timestamp in seconds since 1970‑01‑01T00:00:00Z.
int32_t tz_t
Time zone offset in minutes from UTC (e.g., +180 = UTC+3).
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Conversions and utilities for ISO week dates (ISO 8601).
Main namespace for the Time Shield library.
Structure to represent date and time.
int ms
Millisecond component of time (0-999).
int hour
Hour component of time (0-23).
int64_t year
Year component of the date.
int day
Day component of the date (1-31).
int min
Minute component of time (0-59).
int mon
Month component of the date (1-12).
int sec
Second component of time (0-59).
Structure to represent an ISO week date.
int64_t year
ISO week-numbering year component.
int32_t week
ISO week number component (1-52/53).
Structure to represent time zone information.
int hour
Hour component of time (0-23).
int min
Minute component of time (0-59).
bool is_positive
True if the time zone offset is positive, false if negative.
Umbrella header for time conversion functions.
Header for time zone structure and related functions.