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