Time Shield Library 2.0.0
C++ library for working with time
Loading...
Searching...
No Matches
time_formatting.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2#pragma once
3#ifndef TIME_SHIELD_HEADER_TEXT_TIME_FORMATTING_HPP_INCLUDED
4#define TIME_SHIELD_HEADER_TEXT_TIME_FORMATTING_HPP_INCLUDED
5
12
13#include <time_shield/core.hpp>
15
16#include <inttypes.h>
17
18namespace time_shield {
19
22
24 char last_char,
25 size_t repeat_count,
26 ts_t ts,
27 tz_t utc_offset,
28 const DateTimeStruct& dt,
29 std::string& result) {
30 switch (last_char) {
31 case 'a':
32 if (repeat_count > 1) break;
33 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::SHORT_NAME);
34 break;
35 case 'A':
36 if (repeat_count > 1) break;
37 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::FULL_NAME);
38 break;
39 case 'I':
40 if (repeat_count == 1) {
41 char buffer[4] = {0};
42 snprintf(buffer, sizeof(buffer), "%.2d", hour24_to_12(dt.hour));
43 result += std::string(buffer);
44 }
45 break;
46 case 'H':
47 if (repeat_count <= 2) {
48 char buffer[4] = {0};
49 snprintf(buffer, sizeof(buffer),"%.2d", dt.hour);
50 result += std::string(buffer);
51 }
52 break;
53 case 'h':
54 if (repeat_count == 2) {
55 char buffer[4] = {0};
56 snprintf(buffer, sizeof(buffer),"%.2d", dt.hour);
57 result += std::string(buffer);
58 break;
59 }
60
61 // fallthrough
62 case 'b':
63 // %h: Equivalent to %b
64 if (repeat_count > 1) break;
65 result += to_str(static_cast<Month>(dt.mon), FormatType::SHORT_NAME);
66 break;
67 case 'B':
68 if (repeat_count > 1) break;
69 result += to_str(static_cast<Month>(dt.mon), FormatType::FULL_NAME);
70 break;
71 case 'c':
72 // Preferred date and time representation for the current locale.
73 // %a %b %e %H:%M:%S %Y
74 if (repeat_count <= 1){
75 char buffer[16];
76 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::SHORT_NAME);
77 result += " ";
78 result += to_str(static_cast<Month>(dt.mon), FormatType::SHORT_NAME);
79 result += " ";
80 // added %e
81 std::fill(buffer, buffer + sizeof(buffer), '\0');
82 snprintf(buffer, sizeof(buffer),"%2d ", dt.day);
83 result += std::string(buffer);
84 // added %H:%M:%S
85 std::fill(buffer, buffer + sizeof(buffer), '\0');
86 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d ", dt.hour, dt.min, dt.sec);
87 result += std::string(buffer);
88 // added %Y
89 result += std::to_string(dt.year);
90 }
91 break;
92 case 'C':
93 if (repeat_count > 1) break;
94 result += std::to_string(dt.year/100);
95 break;
96 case 'd':
97 if (repeat_count < 2) {
98 char buffer[4] = {0};
99 snprintf(buffer, sizeof(buffer),"%.2d", dt.day);
100 result += std::string(buffer);
101 }
102 break;
103 case 'D':
104 if (repeat_count == 1) {
105 // %m/%d/%y
106 char buffer[16] = {0};
107 snprintf(buffer, sizeof(buffer), "%.2d/%.2d/%.2d", dt.mon, dt.day, (int)(dt.year % 100LL));
108 result += std::string(buffer);
109 } else
110 if (repeat_count == 2) {
111 char buffer[4] = {0};
112 snprintf(buffer, sizeof(buffer),"%.2d", dt.day);
113 result += std::string(buffer);
114 }
115 break;
116 case 'e':
117 if (repeat_count == 1) {
118 char buffer[4] = {0};
119 snprintf(buffer, sizeof(buffer),"%2d", dt.day);
120 result += std::string(buffer);
121 }
122 break;
123 case 'E':
124 // %E: Modifier for alternative ("era-based") format.
125 // https://help.hcltechsw.com/onedb/1.0.0.1/gug/ids_gug_086.html#ids_gug_086
126 break;
127 case 'F':
128 if (repeat_count == 1) {
129 // %Y-%m-%d ISO 8601 date format
130 char buffer[32] = {0};
131 if (dt.year <= 9999 && dt.year >= 0) {
132 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d", (int)dt.year, dt.mon, dt.day);
133 } else
134 if (dt.year < 0) {
135 snprintf(buffer, sizeof(buffer), "-%" PRId64 "-%.2d-%.2d", dt.year, dt.mon, dt.day);
136 } else {
137 snprintf(buffer, sizeof(buffer), "+%" PRId64 "-%.2d-%.2d", dt.year, dt.mon, dt.day);
138 }
139 result += std::string(buffer);
140 }
141 break;
142 case 'g':
143 // ISO 8601 week-based year without century (2-digit year).
144 if (repeat_count == 1) {
145 const IsoWeekDateStruct iso_week = to_iso_week_date(dt.year, dt.mon, dt.day);
146 const int two_digit_year = static_cast<int>(iso_week.year % 100);
147 char buffer[4] = {0};
148 snprintf(buffer, sizeof(buffer), "%.2d", two_digit_year < 0 ? -two_digit_year : two_digit_year);
149 result += std::string(buffer);
150 }
151 break;
152 case 'G':
153 // ISO 8601 week-based year with century as a decimal number.
154 if (repeat_count == 1) {
155 const IsoWeekDateStruct iso_week = to_iso_week_date(dt.year, dt.mon, dt.day);
156 result += std::to_string(iso_week.year);
157 }
158 break;
159 case 'j':
160 if (repeat_count == 1) {
161 char buffer[4] = {0};
162 snprintf(buffer, sizeof(buffer), "%.3d", day_of_year(ts));
163 result += std::string(buffer);
164 }
165 break;
166 case 'k':
167 if (repeat_count == 1) {
168 char buffer[4] = {0};
169 snprintf(buffer, sizeof(buffer), "%2d", dt.hour);
170 result += std::string(buffer);
171 }
172 break;
173 case 'l':
174 if (repeat_count == 1) {
175 char buffer[4] = {0};
176 snprintf(buffer, sizeof(buffer), "%2d", hour24_to_12(dt.hour));
177 result += std::string(buffer);
178 }
179 break;
180 case 'm':
181 if (repeat_count == 1) {
182 char buffer[4] = {0};
183 snprintf(buffer, sizeof(buffer), "%.2d", dt.mon);
184 result += std::string(buffer);
185 } else
186 if (repeat_count == 2) {
187 char buffer[4] = {0};
188 snprintf(buffer, sizeof(buffer), "%.2d", dt.min);
189 result += std::string(buffer);
190 }
191 break;
192 case 'M':
193 if (repeat_count == 1) {
194 char buffer[4] = {0};
195 snprintf(buffer, sizeof(buffer), "%.2d", dt.min);
196 result += std::string(buffer);
197 } else
198 if (repeat_count == 2) {
199 char buffer[4] = {0};
200 snprintf(buffer, sizeof(buffer), "%.2d", dt.mon);
201 result += std::string(buffer);
202 } else
203 if (repeat_count == 3) {
204 result += to_str(static_cast<Month>(dt.mon), FormatType::UPPERCASE_NAME);
205 }
206 break;
207 case 'n':
208 result += "\n";
209 break;
210 case 'O':
211 // Modifier for using alternative numeric symbols.
212 break;
213 case 'p':
214 if (dt.hour < 12) result += "AM";
215 else result += "PM";
216 break;
217 case 'P':
218 if (dt.hour < 12) result += "am";
219 else result += "pm";
220 break;
221 case 'r':
222 if (repeat_count == 1) {
223 char buffer[16] = {0};
224 if (dt.hour < 12) snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d AM", hour24_to_12(dt.hour), dt.min, dt.sec);
225 else snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d PM", hour24_to_12(dt.hour), dt.min, dt.sec);
226 result += std::string(buffer);
227 break;
228 }
229 break;
230 case 'R':
231 // %H:%M
232 if (repeat_count == 1) {
233 char buffer[8] = {0};
234 snprintf(buffer, sizeof(buffer), "%.2d:%.2d", dt.hour, dt.min);
235 result += std::string(buffer);
236 }
237 break;
238 case 's':
239 if (repeat_count == 1) {
240 result += std::to_string(ts);
241 break;
242 }
243 if (repeat_count == 3) {
244 result += std::to_string(dt.ms);
245 break;
246 }
247 // to '%ss'
248
249 // fallthrough
250 case 'S':
251 if (repeat_count <= 2) {
252 char buffer[4] = {0};
253 snprintf(buffer, sizeof(buffer), "%.2d", dt.sec);
254 result += std::string(buffer);
255 }
256 if (repeat_count == 3) {
257 result += std::to_string(dt.ms);
258 break;
259 }
260 break;
261 case 't':
262 if (repeat_count > 1) break;
263 result += "\t";
264 break;
265 case 'T':
266 // %H:%M:%S
267 if (repeat_count == 1) {
268 char buffer[16] = {0};
269 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d", dt.hour, dt.min, dt.sec);
270 result += std::string(buffer);
271 }
272 break;
273 case 'u':
274 if (repeat_count == 1) {
275 // Day of the week as a decimal number (1 to 7, Monday being 1).
276 int dw = day_of_week(dt.year, dt.mon, dt.day);
277 if (dw == 0) dw = 7;
278 result += std::to_string(dw);
279 }
280 break;
281 case 'U':
282 // Week number of the current year (00 to 53, starting with the first Sunday as week 01).
283 break;
284 case 'V':
285 // ISO 8601 week number of the current year (01 to 53, with specific rules).
286 if (repeat_count == 1) {
287 const IsoWeekDateStruct iso_week = to_iso_week_date(dt.year, dt.mon, dt.day);
288 char buffer[4] = {0};
289 snprintf(buffer, sizeof(buffer), "%.2d", iso_week.week);
290 result += std::string(buffer);
291 }
292 break;
293 case 'w':
294 // Day of the week as a decimal number (0 to 6, Sunday being 0).
295 if (repeat_count == 1) {
296 result += std::to_string(day_of_week(dt.year, dt.mon, dt.day));
297 } else
298 if (repeat_count == 3) {
299 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::SHORT_NAME);
300 }
301 break;
302 case 'W':
303 // Week number of the current year (00 to 53, starting with the first Monday as week 01).
304 if (repeat_count == 3) {
305 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::UPPERCASE_NAME);
306 }
307 break;
308 case 'x':
309 // Preferred date representation for the current locale without the time.
310 break;
311 case 'X':
312 // Preferred time representation for the current locale without the date.
313 break;
314 case 'y':
315 if (repeat_count == 1) {
316 result += std::to_string(dt.year % 100);
317 }
318 break;
319 case 'Y':
320 if (repeat_count == 1) {
321 result += std::to_string(dt.year);
322 } else
323 if (repeat_count == 6) {
324 char buffer[32] = {0};
325 const int64_t mega_years = dt.year / 1000000;
326 const int64_t millennia = (dt.year - mega_years * 1000000) / 1000;
327 const int64_t centuries = dt.year - mega_years * 1000000 - millennia * 1000;
328 if (mega_years) {
329 if (millennia) {
330 snprintf(
331 buffer,
332 sizeof(buffer),
333 "%" PRId64 "M%" PRId64 "K%.3" PRId64,
334 mega_years,
335 static_cast<int64_t>(std::abs(millennia)),
336 static_cast<int64_t>(std::abs(centuries)));
337 } else {
338 snprintf(
339 buffer,
340 sizeof(buffer),
341 "%" PRId64 "M%.3" PRId64,
342 mega_years,
343 static_cast<int64_t>(std::abs(centuries)));
344 }
345 } else
346 if (millennia) {
347 snprintf(
348 buffer,
349 sizeof(buffer),
350 "%" PRId64 "K%.3" PRId64,
351 millennia,
352 static_cast<int64_t>(std::abs(centuries)));
353 } else {
354 snprintf(buffer, sizeof(buffer), "%.4" PRId64, dt.year);
355 }
356 result += std::string(buffer);
357 } else
358 if (repeat_count == 4) {
359 char buffer[8] = {0};
360 snprintf(buffer, sizeof(buffer), "%.4d", (int)(dt.year % 10000));
361 result += std::string(buffer);
362 } else
363 if (repeat_count == 2) {
364 char buffer[8] = {0};
365 snprintf(buffer, sizeof(buffer), "%.2d", (int)(dt.year % 100));
366 result += std::string(buffer);
367 }
368 break;
369 case 'z':
370 // +hhmm or -hhmm numeric timezone offset from UTC.
371 if (repeat_count == 1) {
372 TimeZoneStruct tz = to_time_zone_struct(utc_offset);
373 char buffer[16] = {0};
374 if (tz.is_positive) snprintf(buffer, sizeof(buffer), "+%.2d%.2d", tz.hour, tz.min);
375 else snprintf(buffer, sizeof(buffer), "-%.2d%.2d", tz.hour, tz.min);
376 result += std::string(buffer);
377 }
378 break;
379 case 'Z':
380 // Timezone name or abbreviation.
381
382 result += "UTC";
383 break;
384 case '+':
385 // Date and time in date(1) format (not supported in glibc2).
386 // Tue Jun 4 04:07:43 UTC 2024
387 break;
388 };
389 }
390
421 template<class T = ts_t>
422 const std::string to_string(
423 const std::string& format_str,
424 T timestamp,
425 tz_t utc_offset = 0) {
426 std::string result;
427 if (format_str.empty()) return result;
428 const T local_timestamp = static_cast<T>(timestamp + static_cast<T>(utc_offset));
429 DateTimeStruct dt = to_date_time<DateTimeStruct>(local_timestamp);
430
431 bool is_command = false;
432 size_t repeat_count = 0;
433 char last_char = format_str[0];
434 if (last_char != '%') result += last_char;
435 for (size_t i = 0; i < format_str.size(); ++i) {
436 const char& current_char = format_str[i];
437 if (!is_command) {
438 if (current_char == '%') {
439 ++repeat_count;
440 if (repeat_count == 2) {
441 result += current_char;
442 repeat_count = 0;
443 }
444 continue;
445 }
446 if (!repeat_count) {
447 result += current_char;
448 continue;
449 }
450 last_char = current_char;
451 is_command = true;
452 continue;
453 }
454 if (last_char == current_char) {
455 ++repeat_count;
456 continue;
457 }
458 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
459 repeat_count = 0;
460 is_command = false;
461 --i;
462 }
463 if (is_command) {
464 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
465 }
466 return result;
467 }
468
473 template<class T = ts_t>
474 inline const std::string to_str(
475 const std::string& format_str,
476 T timestamp,
477 tz_t utc_offset = 0) {
478 return to_string<T>(format_str, timestamp, utc_offset);
479 }
480
507 template<class T = ts_ms_t>
508 const std::string to_string_ms(
509 const std::string& format_str,
510 T timestamp,
511 tz_t utc_offset = 0) {
512 std::string result;
513 if (format_str.empty()) return result;
514 const T local_timestamp = static_cast<T>(timestamp + sec_to_ms<T, tz_t>(utc_offset));
516
517 bool is_command = false;
518 size_t repeat_count = 0;
519 char last_char = format_str[0];
520 if (last_char != '%') result += last_char;
521 for (size_t i = 0; i < format_str.size(); ++i) {
522 const char& current_char = format_str[i];
523 if (!is_command) {
524 if (current_char == '%') {
525 ++repeat_count;
526 if (repeat_count == 2) {
527 result += current_char;
528 repeat_count = 0;
529 }
530 continue;
531 }
532 if (!repeat_count) {
533 result += current_char;
534 continue;
535 }
536 last_char = current_char;
537 is_command = true;
538 continue;
539 }
540 if (last_char == current_char) {
541 ++repeat_count;
542 continue;
543 }
544 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
545 repeat_count = 0;
546 is_command = false;
547 --i;
548 }
549 if (is_command) {
550 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
551 }
552 return result;
553 }
554
559 template<class T = ts_t>
560 inline const std::string to_str_ms(
561 const std::string& format_str,
562 T timestamp,
563 tz_t utc_offset = 0) {
564 return to_string_ms<T>(format_str, timestamp, utc_offset);
565 }
566
574 template<class T = ts_t>
575 inline const std::string to_iso8601(T ts) {
577 char buffer[32] = {0};
578 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
579 snprintf(
580 buffer,
581 sizeof(buffer),
582 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d",
583 dt.year,
584 dt.mon,
585 dt.day,
586 dt.hour,
587 dt.min,
588 dt.sec,
589 dt.ms);
590 } else {
591 snprintf(
592 buffer,
593 sizeof(buffer),
594 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d",
595 dt.year,
596 dt.mon,
597 dt.day,
598 dt.hour,
599 dt.min,
600 dt.sec);
601 }
602 return std::string(buffer);
603 }
604
612 template<class T = ts_t>
613 inline const std::string to_iso8601_date(T ts) {
615 char buffer[32] = {0};
616 snprintf(
617 buffer,
618 sizeof(buffer),
619 "%" PRId64 "-%.2d-%.2d",
620 dt.year,
621 dt.mon,
622 dt.day);
623 return std::string(buffer);
624 }
625
633 template<class T = ts_t>
634 inline const std::string to_iso8601_time(T ts) {
636 char buffer[32] = {0};
637 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
638 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d.%.3d", dt.hour, dt.min, dt.sec, dt.ms);
639 } else {
640 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d", dt.hour, dt.min, dt.sec);
641 }
642 return std::string(buffer);
643 }
644
652 template<class T = ts_t>
653 inline const std::string to_iso8601_time_utc(T ts) {
655 char buffer[32] = {0};
656 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
657 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d.%.3dZ", dt.hour, dt.min, dt.sec, dt.ms);
658 } else {
659 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2dZ", dt.hour, dt.min, dt.sec);
660 }
661 return std::string(buffer);
662 }
663
671 template<class T = ts_t>
672 inline const std::string to_iso8601_utc(T ts) {
674 char buffer[32] = {0};
675 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
676 snprintf(
677 buffer,
678 sizeof(buffer),
679 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
680 dt.year,
681 dt.mon,
682 dt.day,
683 dt.hour,
684 dt.min,
685 dt.sec,
686 dt.ms);
687 } else {
688 snprintf(
689 buffer,
690 sizeof(buffer),
691 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2dZ",
692 dt.year,
693 dt.mon,
694 dt.day,
695 dt.hour,
696 dt.min,
697 dt.sec);
698 }
699 return std::string(buffer);
700 }
701
708 inline const std::string to_iso8601_utc_ms(ts_ms_t ts_ms) {
710 char buffer[32] = {0};
711 snprintf(
712 buffer,
713 sizeof(buffer),
714 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
715 dt.year,
716 dt.mon,
717 dt.day,
718 dt.hour,
719 dt.min,
720 dt.sec,
721 dt.ms);
722 return std::string(buffer);
723 }
724
731 inline const std::string to_iso8601_ms(ts_ms_t ts_ms) {
733 char buffer[32] = {0};
734 snprintf(
735 buffer,
736 sizeof(buffer),
737 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d",
738 dt.year,
739 dt.mon,
740 dt.day,
741 dt.hour,
742 dt.min,
743 dt.sec,
744 dt.ms);
745 return std::string(buffer);
746 }
747
756 template<class T = ts_t>
757 inline const std::string to_iso8601(T ts, tz_t utc_offset) {
758 TimeZoneStruct tz = to_time_zone(utc_offset);
759 const T local_ts = static_cast<T>(ts + static_cast<T>(utc_offset));
760 DateTimeStruct dt = to_date_time(local_ts);
761 char buffer[32] = {0};
762 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
763 if (tz.is_positive) {
764 snprintf(
765 buffer,
766 sizeof(buffer),
767 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d+%.2d:%.2d",
768 dt.year,
769 dt.mon,
770 dt.day,
771 dt.hour,
772 dt.min,
773 dt.sec,
774 dt.ms,
775 tz.hour,
776 tz.min);
777 } else {
778 snprintf(
779 buffer,
780 sizeof(buffer),
781 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d-%.2d:%.2d",
782 dt.year,
783 dt.mon,
784 dt.day,
785 dt.hour,
786 dt.min,
787 dt.sec,
788 dt.ms,
789 tz.hour,
790 tz.min);
791 }
792 } else {
793 if (tz.is_positive) {
794 snprintf(
795 buffer,
796 sizeof(buffer),
797 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d+%.2d:%.2d",
798 dt.year,
799 dt.mon,
800 dt.day,
801 dt.hour,
802 dt.min,
803 dt.sec,
804 tz.hour,
805 tz.min);
806 } else {
807 snprintf(
808 buffer,
809 sizeof(buffer),
810 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d-%.2d:%.2d",
811 dt.year,
812 dt.mon,
813 dt.day,
814 dt.hour,
815 dt.min,
816 dt.sec,
817 tz.hour,
818 tz.min);
819 }
820 }
821 return std::string(buffer);
822 }
823
831 inline const std::string to_iso8601_ms(ts_ms_t ts_ms, tz_t utc_offset) {
832 TimeZoneStruct tz = to_time_zone(utc_offset);
833 const ts_ms_t local_ts_ms = ts_ms + sec_to_ms<ts_ms_t, tz_t>(utc_offset);
835 char buffer[32] = {0};
836 if (tz.is_positive) {
837 snprintf(
838 buffer,
839 sizeof(buffer),
840 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d+%.2d:%.2d",
841 dt.year,
842 dt.mon,
843 dt.day,
844 dt.hour,
845 dt.min,
846 dt.sec,
847 dt.ms,
848 tz.hour,
849 tz.min);
850 } else {
851 snprintf(
852 buffer,
853 sizeof(buffer),
854 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d-%.2d:%.2d",
855 dt.year,
856 dt.mon,
857 dt.day,
858 dt.hour,
859 dt.min,
860 dt.sec,
861 dt.ms,
862 tz.hour,
863 tz.min);
864 }
865 return std::string(buffer);
866 }
867
874 inline const std::string to_mql5_date_time(ts_t ts) {
876 char buffer[32] = {0};
877 snprintf(
878 buffer,
879 sizeof(buffer),
880 "%" PRId64 ".%.2d.%.2d %.2d:%.2d:%.2d",
881 dt.year,
882 dt.mon,
883 dt.day,
884 dt.hour,
885 dt.min,
886 dt.sec);
887 return std::string(buffer);
888 }
889
892 inline const std::string to_mql5_full(ts_t ts) {
893 return to_mql5_date_time(ts);
894 }
895
902 inline const std::string to_mql5_date(ts_t ts) {
904 char buffer[32] = {0};
905 snprintf(
906 buffer,
907 sizeof(buffer),
908 "%" PRId64 ".%.2d.%.2d",
909 dt.year,
910 dt.mon,
911 dt.day);
912 return std::string(buffer);
913 }
914
921 inline const std::string to_mql5_time(ts_t ts) {
923 char buffer[32] = {0};
924 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d", dt.hour, dt.min, dt.sec);
925 return std::string(buffer);
926 }
927
931 inline const std::string to_windows_filename(ts_t ts) {
933 char buffer[32] = {0};
934 snprintf(
935 buffer,
936 sizeof(buffer),
937 "%" PRId64 "-%.2d-%.2d_%.2d-%.2d-%.2d",
938 dt.year,
939 dt.mon,
940 dt.day,
941 dt.hour,
942 dt.min,
943 dt.sec);
944 return std::string(buffer);
945 }
946
950 inline const std::string to_windows_filename_ms(ts_ms_t ts) {
952 char buffer[32] = {0};
953 snprintf(
954 buffer,
955 sizeof(buffer),
956 "%" PRId64 "-%.2d-%.2d_%.2d-%.2d-%.2d-%.3d",
957 dt.year,
958 dt.mon,
959 dt.day,
960 dt.hour,
961 dt.min,
962 dt.sec,
963 dt.ms);
964 return std::string(buffer);
965 }
966
970 inline std::string to_human_readable(ts_t ts) {
972 char buffer[32] = {0};
973 snprintf(
974 buffer,
975 sizeof(buffer),
976 "%" PRId64 "-%.2d-%.2d %.2d:%.2d:%.2d",
977 dt.year,
978 dt.mon,
979 dt.day,
980 dt.hour,
981 dt.min,
982 dt.sec);
983 return std::string(buffer);
984 }
985
989 inline std::string to_human_readable_ms(ts_ms_t ts) {
991 char buffer[32] = {0};
992 snprintf(
993 buffer,
994 sizeof(buffer),
995 "%" PRId64 "-%.2d-%.2d %.2d:%.2d:%.2d.%.3d",
996 dt.year,
997 dt.mon,
998 dt.day,
999 dt.hour,
1000 dt.min,
1001 dt.sec,
1002 dt.ms);
1003 return std::string(buffer);
1004 }
1005
1007
1008}; // namespace time_shield
1009
1010#endif // TIME_SHIELD_HEADER_TEXT_TIME_FORMATTING_HPP_INCLUDED
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 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.
Definition enums.hpp:70
const std::string to_iso8601_ms(ts_ms_t ts_ms)
Converts a timestamp in milliseconds to an ISO8601 string.
const std::string to_mql5_date_time(ts_t ts)
Converts a timestamp to a string in MQL5 date and time format.
const std::string to_iso8601_time(T ts)
Converts a timestamp to an ISO8601 time string.
void process_format_impl(char last_char, size_t repeat_count, ts_t ts, tz_t utc_offset, const DateTimeStruct &dt, std::string &result)
const std::string to_windows_filename(ts_t ts)
Converts a timestamp in seconds to a Windows-compatible filename format.
const std::string to_iso8601_date(T ts)
Converts a timestamp to an ISO8601 date string.
const std::string to_mql5_date(ts_t ts)
Converts a timestamp to a string in MQL5 date format.
const std::string to_mql5_full(ts_t ts)
Alias for to_mql5_date_time_str function.
const std::string to_mql5_time(ts_t ts)
Converts a timestamp to a string in MQL5 time format.
const std::string to_str_ms(const std::string &format_str, T timestamp, tz_t utc_offset=0)
Alias for to_string function.
std::string to_human_readable(ts_t ts)
Converts a timestamp in seconds to a human-readable format.
const std::string to_iso8601_utc_ms(ts_ms_t ts_ms)
Converts a timestamp in milliseconds to an ISO8601 string in UTC format.
const std::string to_iso8601(T ts)
Converts a timestamp to an ISO8601 string.
std::string to_human_readable_ms(ts_ms_t ts)
Converts a timestamp in milliseconds to a human-readable format.
const std::string to_iso8601_time_utc(T ts)
Converts a timestamp to an ISO8601 UTC time string.
const std::string to_string_ms(const std::string &format_str, T timestamp, tz_t utc_offset=0)
Convert timestamp in milliseconds to string with custom format.
const std::string to_windows_filename_ms(ts_ms_t ts)
Converts a timestamp in milliseconds to a Windows-compatible filename format.
const std::string to_iso8601_utc(T ts)
Converts a timestamp to an ISO8601 string in UTC format.
TimeZoneStruct to_time_zone_struct(tz_t offset)
Converts an integer to a TimeZoneStruct.
std::string to_string(const TimeZoneStruct &tz)
Alias for time_zone_struct_to_string function.
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.
Definition types.hpp:48
int32_t tz_t
Time zone offset in minutes from UTC (e.g., +180 = UTC+3).
Definition types.hpp:60
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:49
ts_t ts() noexcept
Get the current UTC timestamp in seconds.
ts_t timestamp() noexcept
Get the current UTC timestamp in seconds.
ts_ms_t ts_ms() noexcept
Get the current UTC timestamp in milliseconds.
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.