Time Shield Library
C++ library for working with time
Loading...
Searching...
No Matches
time_formatting.mqh
Go to the documentation of this file.
1//+------------------------------------------------------------------+
2//| time_formatting.mqh |
3//| Time Shield - MQL5 Time Formatting |
4//| Copyright 2025, NewYaroslav |
5//| https://github.com/NewYaroslav/time-shield-cpp |
6//+------------------------------------------------------------------+
7#ifndef __TIME_SHIELD_TIME_FORMATTING_MQH__
8#define __TIME_SHIELD_TIME_FORMATTING_MQH__
9
17
18#property copyright "Copyright 2025, NewYaroslav"
19#property link "https://github.com/NewYaroslav/time-shield-cpp"
20#property strict
21
25#include <time_shield/enums.mqh>
26
27namespace time_shield {
28
32
37 string pad_int(int value, int width) {
38 string s = IntegerToString(value);
39 while(StringLen(s) < width)
40 s = "0" + s;
41 return s;
42 }
43
44 //----------------------------------------------------------------------
45 // Custom formatting
46 //----------------------------------------------------------------------
47
60 const char last_char,
61 int repeat_count,
62 long ts,
63 int utc_offset,
64 const DateTimeStruct &dt,
65 string &result)
66 {
67 switch(last_char) {
68 case 'a':
69 if(repeat_count<=1)
70 result += to_str(day_of_week(dt.year, dt.mon, dt.day), SHORT_NAME);
71 break;
72 case 'A':
73 if(repeat_count<=1)
74 result += to_str(day_of_week(dt.year, dt.mon, dt.day), FULL_NAME);
75 break;
76 case 'I':
77 if(repeat_count==1)
78 result += pad_int(hour24_to_12(dt.hour),2);
79 break;
80 case 'H':
81 if(repeat_count<=2)
82 result += pad_int(dt.hour,2);
83 break;
84 case 'h':
85 if(repeat_count==2)
86 result += pad_int(dt.hour,2);
87 else
88 result += to_str((Month)dt.mon, SHORT_NAME);
89 break;
90 case 'b':
91 if(repeat_count<=1)
92 result += to_str((Month)dt.mon, SHORT_NAME);
93 break;
94 case 'B':
95 if(repeat_count<=1)
96 result += to_str((Month)dt.mon, FULL_NAME);
97 break;
98 case 'c':
99 if(repeat_count<=1) {
100 result += to_str(day_of_week(dt.year, dt.mon, dt.day), SHORT_NAME)+" ";
101 result += to_str((Month)dt.mon, SHORT_NAME)+" ";
102 result += StringFormat("%2d ", dt.day);
103 result += StringFormat("%02d:%02d:%02d ", dt.hour, dt.min, dt.sec);
104 result += IntegerToString(dt.year);
105 }
106 break;
107 case 'C':
108 if(repeat_count<=1)
109 result += IntegerToString(dt.year/100);
110 break;
111 case 'd':
112 if(repeat_count<2)
113 result += pad_int(dt.day,2);
114 break;
115 case 'D':
116 if(repeat_count==1)
117 result += StringFormat("%02d/%02d/%02d", dt.mon, dt.day, (int)(dt.year%100));
118 else if(repeat_count==2)
119 result += pad_int(dt.day,2);
120 break;
121 case 'e':
122 if(repeat_count==1)
123 result += StringFormat("%2d", dt.day);
124 break;
125 case 'F':
126 if(repeat_count==1)
127 result += StringFormat("%lld-%02d-%02d", dt.year, dt.mon, dt.day);
128 break;
129 case 'j':
130 if(repeat_count==1)
131 result += pad_int(day_of_year(ts),3);
132 break;
133 case 'k':
134 if(repeat_count==1)
135 result += StringFormat("%2d", dt.hour);
136 break;
137 case 'l':
138 if(repeat_count==1)
139 result += StringFormat("%2d", hour24_to_12(dt.hour));
140 break;
141 case 'm':
142 if(repeat_count==1)
143 result += pad_int(dt.mon,2);
144 else if(repeat_count==2)
145 result += pad_int(dt.min,2);
146 break;
147 case 'M':
148 if(repeat_count==1)
149 result += pad_int(dt.min,2);
150 else if(repeat_count==2)
151 result += pad_int(dt.mon,2);
152 else if(repeat_count==3)
153 result += to_str((Month)dt.mon, UPPERCASE_NAME);
154 break;
155 case 'n':
156 result += "\n";
157 break;
158 case 'p':
159 result += dt.hour<12?"AM":"PM";
160 break;
161 case 'P':
162 result += dt.hour<12?"am":"pm";
163 break;
164 case 'r':
165 if(repeat_count==1)
166 result += StringFormat("%02d:%02d:%02d %s", hour24_to_12(dt.hour), dt.min, dt.sec, dt.hour<12?"AM":"PM");
167 break;
168 case 'R':
169 if(repeat_count==1)
170 result += StringFormat("%02d:%02d", dt.hour, dt.min);
171 break;
172 case 's':
173 if(repeat_count==1)
174 result += IntegerToString(ts);
175 else if(repeat_count==3)
176 result += IntegerToString(dt.ms);
177 break;
178 case 'S':
179 if(repeat_count<=2)
180 result += pad_int(dt.sec,2);
181 if(repeat_count==3)
182 result += IntegerToString(dt.ms);
183 break;
184 case 't':
185 if(repeat_count<=1)
186 result += "\t";
187 break;
188 case 'T':
189 if(repeat_count==1)
190 result += StringFormat("%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
191 break;
192 case 'u':
193 if(repeat_count==1) {
194 int dw = day_of_week(dt.year, dt.mon, dt.day);
195 if(dw==0) dw=7;
196 result += IntegerToString(dw);
197 }
198 break;
199 case 'w':
200 if(repeat_count==1)
201 result += IntegerToString(day_of_week(dt.year, dt.mon, dt.day));
202 else if(repeat_count==3)
203 result += to_str(day_of_week(dt.year, dt.mon, dt.day), SHORT_NAME);
204 break;
205 case 'W':
206 if(repeat_count==3)
207 result += to_str(day_of_week(dt.year, dt.mon, dt.day), UPPERCASE_NAME);
208 break;
209 case 'y':
210 if(repeat_count==1)
211 result += IntegerToString(dt.year%100);
212 break;
213 case 'Y':
214 if(repeat_count==1)
215 result += IntegerToString(dt.year);
216 break;
217 case 'z':
218 if(repeat_count==1) {
219 TimeZoneStruct tz = to_time_zone_struct(utc_offset);
220 string sign = tz.is_positive?"+":"-";
221 result += sign+pad_int(tz.hour,2)+pad_int(tz.min,2);
222 }
223 break;
224 case 'Z':
225 result += "UTC";
226 break;
227 }
228 }
229
239 string to_string(const string &format_str, long timestamp, int utc_offset=0) {
240 string result="";
241 if(StringLen(format_str)==0) return result;
243 bool is_command=false;
244 int repeat_count=0;
245 char last_char = StringGetChar(format_str,0);
246 if(last_char!='%') result+=CharToString(last_char);
247 for(int i=0;i<StringLen(format_str);++i) {
248 char current_char = StringGetChar(format_str,i);
249 if(!is_command) {
250 if(current_char=='%') {
251 ++repeat_count;
252 if(repeat_count==2) {
253 result += "%";
254 repeat_count=0;
255 }
256 continue;
257 }
258 if(!repeat_count) {
259 result += CharToString(current_char);
260 continue;
261 }
262 last_char=current_char;
263 is_command=true;
264 continue;
265 }
266 if(last_char==current_char) {
267 ++repeat_count;
268 continue;
269 }
270 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
271 repeat_count=0;
272 is_command=false;
273 --i;
274 }
275 if(is_command)
276 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
277 return result;
278 }
279
282 string to_str(const string &format_str, long timestamp, int utc_offset=0) {
283 return to_string(format_str, timestamp, utc_offset);
284 }
285
294 string to_string_ms(const string &format_str, long timestamp_ms, int utc_offset=0) {
295 string result="";
296 if(StringLen(format_str)==0) return result;
298 bool is_command=false;
299 int repeat_count=0;
300 char last_char = StringGetChar(format_str,0);
301 if(last_char!='%') result+=CharToString(last_char);
302 for(int i=0;i<StringLen(format_str);++i) {
303 char current_char = StringGetChar(format_str,i);
304 if(!is_command) {
305 if(current_char=='%') {
306 ++repeat_count;
307 if(repeat_count==2) {
308 result += "%";
309 repeat_count=0;
310 }
311 continue;
312 }
313 if(!repeat_count) {
314 result += CharToString(current_char);
315 continue;
316 }
317 last_char=current_char;
318 is_command=true;
319 continue;
320 }
321 if(last_char==current_char) {
322 ++repeat_count;
323 continue;
324 }
325 process_format_impl(last_char, repeat_count, ms_to_sec(timestamp_ms), utc_offset, dt, result);
326 repeat_count=0;
327 is_command=false;
328 --i;
329 }
330 if(is_command)
331 process_format_impl(last_char, repeat_count, ms_to_sec(timestamp_ms), utc_offset, dt, result);
332 return result;
333 }
334
337 string to_str_ms(const string &format_str, long timestamp_ms, int utc_offset=0) {
338 return to_string_ms(format_str, timestamp_ms, utc_offset);
339 }
340
341 //----------------------------------------------------------------------
342 // ISO8601 helpers
343 //----------------------------------------------------------------------
344
348 string to_iso8601(long ts) {
350 return StringFormat("%lld-%02d-%02dT%02d:%02d:%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
351 }
352
356 string to_iso8601_ms(long ts_ms) {
358 return StringFormat("%lld-%02d-%02dT%02d:%02d:%02d.%03d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
359 }
360
364 string to_iso8601_date(long ts) {
366 return StringFormat("%lld-%02d-%02d", dt.year, dt.mon, dt.day);
367 }
368
372 string to_iso8601_time(long ts) {
374 return StringFormat("%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
375 }
376
382 return StringFormat("%02d:%02d:%02d.%03d", dt.hour, dt.min, dt.sec, dt.ms);
383 }
384
388 string to_iso8601_utc(long ts) {
389 return to_iso8601(ts)+"Z";
390 }
391
396 return to_iso8601_ms(ts_ms)+"Z";
397 }
398
403 string to_iso8601(long ts, int utc_offset) {
404 TimeZoneStruct tz = to_time_zone(utc_offset);
405 string sign = tz.is_positive?"+":"-";
406 return StringFormat("%s%s%.2d:%.2d", to_iso8601(ts), sign, tz.hour, tz.min);
407 }
408
413 string to_iso8601_ms(long ts_ms, int utc_offset) {
414 TimeZoneStruct tz = to_time_zone(utc_offset);
415 string sign = tz.is_positive?"+":"-";
416 return StringFormat("%s%s%.2d:%.2d", to_iso8601_ms(ts_ms), sign, tz.hour, tz.min);
417 }
418
419 //----------------------------------------------------------------------
420 // MQL5 specific helpers
421 //----------------------------------------------------------------------
422
426 string to_mql5_date_time(long ts) {
428 return StringFormat("%lld.%02d.%02d %02d:%02d:%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
429 }
430
434 string to_mql5_date(long ts) {
436 return StringFormat("%lld.%02d.%02d", dt.year, dt.mon, dt.day);
437 }
438
442 string to_mql5_time(long ts) {
444 return StringFormat("%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
445 }
446
449 string to_mql5_full(long ts) { return to_mql5_date_time(ts); }
450
454 string to_windows_filename(long ts) {
456 return StringFormat("%lld-%02d-%02d_%02d-%02d-%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
457 }
458
464 return StringFormat("%lld-%02d-%02d_%02d-%02d-%02d-%03d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
465 }
466
470 string to_human_readable(long ts) {
472 return StringFormat("%lld-%02d-%02d %02d:%02d:%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
473 }
474
480 return StringFormat("%lld-%02d-%02d %02d:%02d:%02d.%03d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
481 }
482
484
485}; // namespace time_shield
486
487#endif // __TIME_SHIELD_TIME_FORMATTING_MQH__
Header for date and time structure and related functions (MQL5).
Header file with enumerations for weekdays, months, and other time-related categories.
TIME_SHIELD_CONSTEXPR const ts_t timestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0)
Alias for to_timestamp function.
TIME_SHIELD_CONSTEXPR const ts_t ts(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0)
Alias for to_timestamp function.
const T to_time_zone(tz_t offset)
Converts an integer to a time zone structure.
constexpr const T1 day_of_week(T2 year, T3 month, T3 day)
Alias for day_of_week_date function.
TIME_SHIELD_CONSTEXPR const T hour24_to_12(T hour) noexcept
Converts a 24-hour format hour to a 12-hour format.
TIME_SHIELD_CONSTEXPR const ts_ms_t timestamp_ms(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T2 ms=0)
Alias for to_timestamp_ms function.
TIME_SHIELD_CONSTEXPR const ts_ms_t ts_ms(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T2 ms=0)
Alias for to_timestamp_ms function.
const TimeZoneStruct to_time_zone_struct(tz_t offset)
Converts an integer to a TimeZoneStruct.
constexpr const T1 ms_to_sec(T2 ts_ms) noexcept
Converts a timestamp from milliseconds to seconds.
const T day_of_year(ts_t ts=ts())
Get the day of the year.
const std::string & to_str(Weekday value, FormatType format=UPPERCASE_NAME)
Converts a Weekday enum value to a string.
Definition enums.hpp:82
Month
Enumeration of the months of the year.
Definition enums.hpp:104
@ SHORT_NAME
Short name.
Definition enums.hpp:36
@ FULL_NAME
Full name.
Definition enums.hpp:37
@ UPPERCASE_NAME
Uppercase short name.
Definition enums.hpp:35
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.
string to_iso8601_time_ms(long ts_ms)
Convert millisecond timestamp to ISO8601 time string.
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_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.
string pad_int(int value, int width)
Internal helper to pad integer with leading zeros.
T to_date_time_ms(ts_ms_t ts)
Converts a timestamp in milliseconds to a date-time structure with milliseconds.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
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 with helper functions for converting between different time representations in MQL5.
Header for time zone structure and related functions (MQL5).