Time Shield Library
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_TIME_FORMATTING_HPP_INCLUDED
4#define _TIME_SHIELD_TIME_FORMATTING_HPP_INCLUDED
5
12
13#include "config.hpp"
14#include "date_time_struct.hpp"
15#include "time_zone_struct.hpp"
16#include "time_conversions.hpp"
17
18#include <inttypes.h>
19
20namespace time_shield {
21
24
26 char last_char,
27 size_t repeat_count,
28 ts_t ts,
29 tz_t utc_offset,
30 const DateTimeStruct& dt,
31 std::string& result) {
32 switch (last_char) {
33 case 'a':
34 if (repeat_count > 1) break;
35 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::SHORT_NAME);
36 break;
37 case 'A':
38 if (repeat_count > 1) break;
39 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::FULL_NAME);
40 break;
41 case 'I':
42 if (repeat_count == 1) {
43 char buffer[4] = {0};
44 snprintf(buffer, sizeof(buffer), "%.2d", hour24_to_12(dt.hour));
45 result += std::string(buffer);
46 }
47 break;
48 case 'H':
49 if (repeat_count <= 2) {
50 char buffer[4] = {0};
51 snprintf(buffer, sizeof(buffer),"%.2d", dt.hour);
52 result += std::string(buffer);
53 }
54 break;
55 case 'h':
56 if (repeat_count == 2) {
57 char buffer[4] = {0};
58 snprintf(buffer, sizeof(buffer),"%.2d", dt.hour);
59 result += std::string(buffer);
60 break;
61 }
62
63 // fallthrough
64 case 'b':
65 // %h: Equivalent to %b
66 if (repeat_count > 1) break;
67 result += to_str(static_cast<Month>(dt.mon), FormatType::SHORT_NAME);
68 break;
69 case 'B':
70 if (repeat_count > 1) break;
71 result += to_str(static_cast<Month>(dt.mon), FormatType::FULL_NAME);
72 break;
73 case 'c':
74 // Preferred date and time representation for the current locale.
75 // %a %b %e %H:%M:%S %Y
76 if (repeat_count <= 1){
77 char buffer[16];
78 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::SHORT_NAME);
79 result += " ";
80 result += to_str(static_cast<Month>(dt.mon), FormatType::SHORT_NAME);
81 result += " ";
82 // added %e
83 std::fill(buffer, buffer + sizeof(buffer), '\0');
84 snprintf(buffer, sizeof(buffer),"%2d ", dt.day);
85 result += std::string(buffer);
86 // added %H:%M:%S
87 std::fill(buffer, buffer + sizeof(buffer), '\0');
88 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d ", dt.hour, dt.min, dt.sec);
89 result += std::string(buffer);
90 // added %Y
91 result += std::to_string(dt.year);
92 }
93 break;
94 case 'C':
95 if (repeat_count > 1) break;
96 result += std::to_string(dt.year/100);
97 break;
98 case 'd':
99 if (repeat_count < 2) {
100 char buffer[4] = {0};
101 snprintf(buffer, sizeof(buffer),"%.2d", dt.day);
102 result += std::string(buffer);
103 }
104 break;
105 case 'D':
106 if (repeat_count == 1) {
107 // %m/%d/%y
108 char buffer[16] = {0};
109 snprintf(buffer, sizeof(buffer), "%.2d/%.2d/%.2d", dt.mon, dt.day, (int)(dt.year % 100LL));
110 result += std::string(buffer);
111 } else
112 if (repeat_count == 2) {
113 char buffer[4] = {0};
114 snprintf(buffer, sizeof(buffer),"%.2d", dt.day);
115 result += std::string(buffer);
116 }
117 break;
118 case 'e':
119 if (repeat_count == 1) {
120 char buffer[4] = {0};
121 snprintf(buffer, sizeof(buffer),"%2d", dt.day);
122 result += std::string(buffer);
123 }
124 break;
125 case 'E':
126 // %E: Modifier for alternative ("era-based") format.
127 // https://help.hcltechsw.com/onedb/1.0.0.1/gug/ids_gug_086.html#ids_gug_086
128 break;
129 case 'F':
130 if (repeat_count == 1) {
131 // %Y-%m-%d ISO 8601 date format
132 char buffer[32] = {0};
133 if (dt.year <= 9999 && dt.year >= 0) {
134 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d", (int)dt.year, dt.mon, dt.day);
135 } else
136 if (dt.year < 0) {
137 snprintf(buffer, sizeof(buffer), "-%" PRId64 "-%.2d-%.2d", dt.year, dt.mon, dt.day);
138 } else {
139 snprintf(buffer, sizeof(buffer), "+%" PRId64 "-%.2d-%.2d", dt.year, dt.mon, dt.day);
140 }
141 result += std::string(buffer);
142 }
143 case 'g':
144 // ISO 8601 week-based year without century (2-digit year).
145 break;
146 case 'G':
147 // ISO 8601 week-based year with century as a decimal number.
148 break;
149 case 'j':
150 if (repeat_count == 1) {
151 char buffer[4] = {0};
152 snprintf(buffer, sizeof(buffer), "%.3d", day_of_year(ts));
153 result += std::string(buffer);
154 }
155 break;
156 case 'k':
157 if (repeat_count == 1) {
158 char buffer[4] = {0};
159 snprintf(buffer, sizeof(buffer), "%2d", dt.hour);
160 result += std::string(buffer);
161 }
162 break;
163 case 'l':
164 if (repeat_count == 1) {
165 char buffer[4] = {0};
166 snprintf(buffer, sizeof(buffer), "%2d", hour24_to_12(dt.hour));
167 result += std::string(buffer);
168 }
169 break;
170 case 'm':
171 if (repeat_count == 1) {
172 char buffer[4] = {0};
173 snprintf(buffer, sizeof(buffer), "%.2d", dt.mon);
174 result += std::string(buffer);
175 } else
176 if (repeat_count == 2) {
177 char buffer[4] = {0};
178 snprintf(buffer, sizeof(buffer), "%.2d", dt.min);
179 result += std::string(buffer);
180 }
181 break;
182 case 'M':
183 if (repeat_count == 1) {
184 char buffer[4] = {0};
185 snprintf(buffer, sizeof(buffer), "%.2d", dt.min);
186 result += std::string(buffer);
187 } else
188 if (repeat_count == 2) {
189 char buffer[4] = {0};
190 snprintf(buffer, sizeof(buffer), "%.2d", dt.mon);
191 result += std::string(buffer);
192 } else
193 if (repeat_count == 3) {
194 result += to_str(static_cast<Month>(dt.mon), FormatType::UPPERCASE_NAME);
195 }
196 break;
197 case 'n':
198 result += "\n";
199 break;
200 case 'O':
201 // Modifier for using alternative numeric symbols.
202 break;
203 case 'p':
204 if (dt.hour < 12) result += "AM";
205 else result += "PM";
206 break;
207 case 'P':
208 if (dt.hour < 12) result += "am";
209 else result += "pm";
210 break;
211 case 'r':
212 if (repeat_count == 1) {
213 char buffer[16] = {0};
214 if (dt.hour < 12) snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d AM", hour24_to_12(dt.hour), dt.min, dt.sec);
215 else snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d PM", hour24_to_12(dt.hour), dt.min, dt.sec);
216 result += std::string(buffer);
217 break;
218 }
219 break;
220 case 'R':
221 // %H:%M
222 if (repeat_count == 1) {
223 char buffer[8] = {0};
224 snprintf(buffer, sizeof(buffer), "%.2d:%.2d", dt.hour, dt.min);
225 result += std::string(buffer);
226 }
227 break;
228 case 's':
229 if (repeat_count == 1) {
230 result += std::to_string(ts);
231 break;
232 }
233 if (repeat_count == 3) {
234 result += std::to_string(dt.ms);
235 break;
236 }
237 // to '%ss'
238
239 // fallthrough
240 case 'S':
241 if (repeat_count <= 2) {
242 char buffer[4] = {0};
243 snprintf(buffer, sizeof(buffer), "%.2d", dt.sec);
244 result += std::string(buffer);
245 }
246 if (repeat_count == 3) {
247 result += std::to_string(dt.ms);
248 break;
249 }
250 break;
251 case 't':
252 if (repeat_count > 1) break;
253 result += "\t";
254 break;
255 case 'T':
256 // %H:%M:%S
257 if (repeat_count == 1) {
258 char buffer[16] = {0};
259 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d", dt.hour, dt.min, dt.sec);
260 result += std::string(buffer);
261 }
262 break;
263 case 'u':
264 if (repeat_count == 1) {
265 // Day of the week as a decimal number (1 to 7, Monday being 1).
266 int dw = day_of_week(dt.year, dt.mon, dt.day);
267 if (dw == 0) dw = 7;
268 result += std::to_string(dw);
269 }
270 break;
271 case 'U':
272 // Week number of the current year (00 to 53, starting with the first Sunday as week 01).
273 break;
274 case 'V':
275 // ISO 8601 week number of the current year (01 to 53, with specific rules).
276 break;
277 case 'w':
278 // Day of the week as a decimal number (0 to 6, Sunday being 0).
279 if (repeat_count == 1) {
280 result += std::to_string(day_of_week(dt.year, dt.mon, dt.day));
281 } else
282 if (repeat_count == 3) {
283 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::SHORT_NAME);
284 }
285 break;
286 case 'W':
287 // Week number of the current year (00 to 53, starting with the first Monday as week 01).
288 if (repeat_count == 3) {
289 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FormatType::UPPERCASE_NAME);
290 }
291 break;
292 case 'x':
293 // Preferred date representation for the current locale without the time.
294 break;
295 case 'X':
296 // Preferred time representation for the current locale without the date.
297 break;
298 case 'y':
299 if (repeat_count == 1) {
300 result += std::to_string(dt.year % 100);
301 }
302 break;
303 case 'Y':
304 if (repeat_count == 1) {
305 result += std::to_string(dt.year);
306 } else
307 if (repeat_count == 6) {
308 char buffer[32] = {0};
309 const int64_t mega_years = dt.year / 1000000;
310 const int64_t millennia = (dt.year - mega_years * 1000000) / 1000;
311 const int64_t centuries = dt.year - mega_years * 1000000 - millennia * 1000;
312 if (mega_years) {
313 if (millennia) {
314 snprintf(
315 buffer,
316 sizeof(buffer),
317 "%" PRId64 "M%" PRId64 "K%.3" PRId64,
318 mega_years,
319 static_cast<int64_t>(std::abs(millennia)),
320 static_cast<int64_t>(std::abs(centuries)));
321 } else {
322 snprintf(
323 buffer,
324 sizeof(buffer),
325 "%" PRId64 "M%.3" PRId64,
326 mega_years,
327 static_cast<int64_t>(std::abs(centuries)));
328 }
329 } else
330 if (millennia) {
331 snprintf(
332 buffer,
333 sizeof(buffer),
334 "%" PRId64 "K%.3" PRId64,
335 millennia,
336 static_cast<int64_t>(std::abs(centuries)));
337 } else {
338 snprintf(buffer, sizeof(buffer), "%.4" PRId64, dt.year);
339 }
340 result += std::string(buffer);
341 } else
342 if (repeat_count == 4) {
343 char buffer[8] = {0};
344 snprintf(buffer, sizeof(buffer), "%.4d", (int)(dt.year % 10000));
345 result += std::string(buffer);
346 } else
347 if (repeat_count == 2) {
348 char buffer[8] = {0};
349 snprintf(buffer, sizeof(buffer), "%.2d", (int)(dt.year % 100));
350 result += std::string(buffer);
351 }
352 break;
353 case 'z':
354 // +hhmm or -hhmm numeric timezone offset from UTC.
355 if (repeat_count == 1) {
356 TimeZoneStruct tz = to_time_zone_struct(utc_offset);
357 char buffer[16] = {0};
358 if (tz.is_positive) snprintf(buffer, sizeof(buffer), "+%.2d%.2d", tz.hour, tz.min);
359 else snprintf(buffer, sizeof(buffer), "-%.2d%.2d", tz.hour, tz.min);
360 result += std::string(buffer);
361 }
362 break;
363 case 'Z':
364 // Timezone name or abbreviation.
365
366 result += "UTC";
367 break;
368 case '+':
369 // Date and time in date(1) format (not supported in glibc2).
370 // Tue Jun 4 04:07:43 UTC 2024
371 break;
372 };
373 }
374
401 template<class T = ts_t>
402 const std::string to_string(
403 const std::string& format_str,
404 T timestamp,
405 tz_t utc_offset = 0) {
406 std::string result;
407 if (format_str.empty()) return result;
409
410 bool is_command = false;
411 size_t repeat_count = 0;
412 char last_char = format_str[0];
413 if (last_char != '%') result += last_char;
414 for (size_t i = 0; i < format_str.size(); ++i) {
415 const char& current_char = format_str[i];
416 if (!is_command) {
417 if (current_char == '%') {
418 ++repeat_count;
419 if (repeat_count == 2) {
420 result += current_char;
421 repeat_count = 0;
422 }
423 continue;
424 }
425 if (!repeat_count) {
426 result += current_char;
427 continue;
428 }
429 last_char = current_char;
430 is_command = true;
431 continue;
432 }
433 if (last_char == current_char) {
434 ++repeat_count;
435 continue;
436 }
437 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
438 repeat_count = 0;
439 is_command = false;
440 --i;
441 }
442 if (is_command) {
443 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
444 }
445 return result;
446 }
447
450 template<class T = ts_t>
451 inline const std::string to_str(
452 const std::string& format_str,
453 T timestamp,
454 tz_t utc_offset = 0) {
455 return to_string<T>(format_str, timestamp, utc_offset);
456 }
457
484 template<class T = ts_ms_t>
485 const std::string to_string_ms(
486 const std::string& format_str,
487 T timestamp,
488 tz_t utc_offset = 0) {
489 std::string result;
490 if (format_str.empty()) return result;
492
493 bool is_command = false;
494 size_t repeat_count = 0;
495 char last_char = format_str[0];
496 if (last_char != '%') result += last_char;
497 for (size_t i = 0; i < format_str.size(); ++i) {
498 const char& current_char = format_str[i];
499 if (!is_command) {
500 if (current_char == '%') {
501 ++repeat_count;
502 if (repeat_count == 2) {
503 result += current_char;
504 repeat_count = 0;
505 }
506 continue;
507 }
508 if (!repeat_count) {
509 result += current_char;
510 continue;
511 }
512 last_char = current_char;
513 is_command = true;
514 continue;
515 }
516 if (last_char == current_char) {
517 ++repeat_count;
518 continue;
519 }
520 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
521 repeat_count = 0;
522 is_command = false;
523 --i;
524 }
525 if (is_command) {
526 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
527 }
528 return result;
529 }
530
533 template<class T = ts_t>
534 inline const std::string to_str_ms(
535 const std::string& format_str,
536 T timestamp,
537 tz_t utc_offset = 0) {
538 return to_string_ms<T>(format_str, timestamp, utc_offset);
539 }
540
548 template<class T = ts_t>
549 inline const std::string to_iso8601(T ts) {
551 char buffer[32] = {0};
552 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
553 snprintf(
554 buffer,
555 sizeof(buffer),
556 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d",
557 dt.year,
558 dt.mon,
559 dt.day,
560 dt.hour,
561 dt.min,
562 dt.sec,
563 dt.ms);
564 } else {
565 snprintf(
566 buffer,
567 sizeof(buffer),
568 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d",
569 dt.year,
570 dt.mon,
571 dt.day,
572 dt.hour,
573 dt.min,
574 dt.sec);
575 }
576 return std::string(buffer);
577 }
578
586 template<class T = ts_t>
587 inline const std::string to_iso8601_date(T ts) {
589 char buffer[32] = {0};
590 snprintf(
591 buffer,
592 sizeof(buffer),
593 "%" PRId64 "-%.2d-%.2d",
594 dt.year,
595 dt.mon,
596 dt.day);
597 return std::string(buffer);
598 }
599
607 template<class T = ts_t>
608 inline const std::string to_iso8601_time(T ts) {
610 char buffer[32] = {0};
611 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
612 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d.%.3d", dt.hour, dt.min, dt.sec, dt.ms);
613 } else {
614 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d", dt.hour, dt.min, dt.sec);
615 }
616 return std::string(buffer);
617 }
618
626 template<class T = ts_t>
627 inline const std::string to_iso8601_time_utc(T ts) {
629 char buffer[32] = {0};
630 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
631 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d.%.3dZ", dt.hour, dt.min, dt.sec, dt.ms);
632 } else {
633 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2dZ", dt.hour, dt.min, dt.sec);
634 }
635 return std::string(buffer);
636 }
637
645 template<class T = ts_t>
646 inline const std::string to_iso8601_utc(T ts) {
648 char buffer[32] = {0};
649 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
650 snprintf(
651 buffer,
652 sizeof(buffer),
653 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
654 dt.year,
655 dt.mon,
656 dt.day,
657 dt.hour,
658 dt.min,
659 dt.sec,
660 dt.ms);
661 } else {
662 snprintf(
663 buffer,
664 sizeof(buffer),
665 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2dZ",
666 dt.year,
667 dt.mon,
668 dt.day,
669 dt.hour,
670 dt.min,
671 dt.sec);
672 }
673 return std::string(buffer);
674 }
675
682 inline const std::string to_iso8601_utc_ms(ts_ms_t ts_ms) {
684 char buffer[32] = {0};
685 snprintf(
686 buffer,
687 sizeof(buffer),
688 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
689 dt.year,
690 dt.mon,
691 dt.day,
692 dt.hour,
693 dt.min,
694 dt.sec,
695 dt.ms);
696 return std::string(buffer);
697 }
698
705 inline const std::string to_iso8601_ms(ts_ms_t ts_ms) {
707 char buffer[32] = {0};
708 snprintf(
709 buffer,
710 sizeof(buffer),
711 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d",
712 dt.year,
713 dt.mon,
714 dt.day,
715 dt.hour,
716 dt.min,
717 dt.sec,
718 dt.ms);
719 return std::string(buffer);
720 }
721
730 template<class T = ts_t>
731 inline const std::string to_iso8601(T ts, tz_t utc_offset) {
732 TimeZoneStruct tz = to_time_zone(utc_offset);
734 char buffer[32] = {0};
735 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T>::value) {
736 if (tz.is_positive) {
737 snprintf(
738 buffer,
739 sizeof(buffer),
740 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d+%.2d:%.2d",
741 dt.year,
742 dt.mon,
743 dt.day,
744 dt.hour,
745 dt.min,
746 dt.sec,
747 dt.ms,
748 tz.hour,
749 tz.min);
750 } else {
751 snprintf(
752 buffer,
753 sizeof(buffer),
754 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d-%.2d:%.2d",
755 dt.year,
756 dt.mon,
757 dt.day,
758 dt.hour,
759 dt.min,
760 dt.sec,
761 dt.ms,
762 tz.hour,
763 tz.min);
764 }
765 } else {
766 if (tz.is_positive) {
767 snprintf(
768 buffer,
769 sizeof(buffer),
770 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d+%.2d:%.2d",
771 dt.year,
772 dt.mon,
773 dt.day,
774 dt.hour,
775 dt.min,
776 dt.sec,
777 tz.hour,
778 tz.min);
779 } else {
780 snprintf(
781 buffer,
782 sizeof(buffer),
783 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d-%.2d:%.2d",
784 dt.year,
785 dt.mon,
786 dt.day,
787 dt.hour,
788 dt.min,
789 dt.sec,
790 tz.hour,
791 tz.min);
792 }
793 }
794 return std::string(buffer);
795 }
796
804 inline const std::string to_iso8601_ms(ts_ms_t ts_ms, tz_t utc_offset) {
805 TimeZoneStruct tz = to_time_zone(utc_offset);
807 char buffer[32] = {0};
808 if (tz.is_positive) {
809 snprintf(
810 buffer,
811 sizeof(buffer),
812 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d+%.2d:%.2d",
813 dt.year,
814 dt.mon,
815 dt.day,
816 dt.hour,
817 dt.min,
818 dt.sec,
819 dt.ms,
820 tz.hour,
821 tz.min);
822 } else {
823 snprintf(
824 buffer,
825 sizeof(buffer),
826 "%" PRId64 "-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d-%.2d:%.2d",
827 dt.year,
828 dt.mon,
829 dt.day,
830 dt.hour,
831 dt.min,
832 dt.sec,
833 dt.ms,
834 tz.hour,
835 tz.min);
836 }
837 return std::string(buffer);
838 }
839
846 inline const std::string to_mql5_date_time(ts_t ts) {
848 char buffer[32] = {0};
849 snprintf(
850 buffer,
851 sizeof(buffer),
852 "%" PRId64 ".%.2d.%.2d %.2d:%.2d:%.2d",
853 dt.year,
854 dt.mon,
855 dt.day,
856 dt.hour,
857 dt.min,
858 dt.sec);
859 return std::string(buffer);
860 }
861
864 inline const std::string to_mql5_full(ts_t ts) {
865 return to_mql5_date_time(ts);
866 }
867
874 inline const std::string to_mql5_date(ts_t ts) {
876 char buffer[32] = {0};
877 snprintf(
878 buffer,
879 sizeof(buffer),
880 "%" PRId64 ".%.2d.%.2d",
881 dt.year,
882 dt.mon,
883 dt.day);
884 return std::string(buffer);
885 }
886
893 inline const std::string to_mql5_time(ts_t ts) {
895 char buffer[32] = {0};
896 snprintf(buffer, sizeof(buffer), "%.2d:%.2d:%.2d", dt.hour, dt.min, dt.sec);
897 return std::string(buffer);
898 }
899
903 inline const std::string to_windows_filename(ts_t ts) {
905 char buffer[32] = {0};
906 snprintf(
907 buffer,
908 sizeof(buffer),
909 "%" PRId64 "-%.2d-%.2d_%.2d-%.2d-%.2d",
910 dt.year,
911 dt.mon,
912 dt.day,
913 dt.hour,
914 dt.min,
915 dt.sec);
916 return std::string(buffer);
917 }
918
922 inline const std::string to_windows_filename_ms(ts_ms_t ts) {
924 char buffer[32] = {0};
925 snprintf(
926 buffer,
927 sizeof(buffer),
928 "%" PRId64 "-%.2d-%.2d_%.2d-%.2d-%.2d-%.3d",
929 dt.year,
930 dt.mon,
931 dt.day,
932 dt.hour,
933 dt.min,
934 dt.sec,
935 dt.ms);
936 return std::string(buffer);
937 }
938
942 inline std::string to_human_readable(ts_t ts) {
944 char buffer[32] = {0};
945 snprintf(
946 buffer,
947 sizeof(buffer),
948 "%" PRId64 "-%.2d-%.2d %.2d:%.2d:%.2d",
949 dt.year,
950 dt.mon,
951 dt.day,
952 dt.hour,
953 dt.min,
954 dt.sec);
955 return std::string(buffer);
956 }
957
961 inline std::string to_human_readable_ms(ts_ms_t ts) {
963 char buffer[32] = {0};
964 snprintf(
965 buffer,
966 sizeof(buffer),
967 "%" PRId64 "-%.2d-%.2d %.2d:%.2d:%.2d.%.3d",
968 dt.year,
969 dt.mon,
970 dt.day,
971 dt.hour,
972 dt.min,
973 dt.sec,
974 dt.ms);
975 return std::string(buffer);
976 }
977
979
980}; // namespace time_shield
981
982#endif // _TIME_SHIELD_TIME_FORMATTING_HPP_INCLUDED
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.
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.
constexpr T1 day_of_week(year_t year, int month, int day)
Alias for day_of_week_date.
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_string(const std::string &format_str, T timestamp, tz_t utc_offset=0)
Convert timestamp to string with custom format.
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.
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:49
int32_t tz_t
Time zone offset in minutes from UTC (e.g., +180 = UTC+3).
Definition types.hpp:61
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:50
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 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.