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
22#include "enums.mqh"
23#include "date_time_struct.mqh"
24#include "time_zone_struct.mqh"
25#include "time_conversions.mqh"
26
27
28namespace time_shield {
29
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 switch(last_char) {
67 case 'a':
68 if(repeat_count<=1)
69 result += time_shield::to_str(day_of_week(dt.year, dt.mon, dt.day), time_shield::FormatType::SHORT_NAME);
70 break;
71 case 'A':
72 if(repeat_count<=1)
73 result += time_shield::to_str(day_of_week(dt.year, dt.mon, dt.day), time_shield::FormatType::FULL_NAME);
74 break;
75 case 'I':
76 if(repeat_count==1)
77 result += pad_int(hour24_to_12(dt.hour),2);
78 break;
79 case 'H':
80 if(repeat_count<=2)
81 result += pad_int(dt.hour,2);
82 break;
83 case 'h':
84 if(repeat_count==2)
85 result += pad_int(dt.hour,2);
86 else
87 result += to_str((Month)dt.mon, SHORT_NAME);
88 break;
89 case 'b':
90 if(repeat_count<=1)
91 result += to_str((Month)dt.mon, SHORT_NAME);
92 break;
93 case 'B':
94 if(repeat_count<=1)
95 result += to_str((Month)dt.mon, FULL_NAME);
96 break;
97 case 'c':
98 if(repeat_count<=1) {
99 result += to_str(day_of_week(dt.year, dt.mon, dt.day), SHORT_NAME)+" ";
100 result += to_str((Month)dt.mon, SHORT_NAME)+" ";
101 result += StringFormat("%2d ", dt.day);
102 result += StringFormat("%02d:%02d:%02d ", dt.hour, dt.min, dt.sec);
103 result += IntegerToString(dt.year);
104 }
105 break;
106 case 'C':
107 if(repeat_count<=1)
108 result += IntegerToString(dt.year/100);
109 break;
110 case 'd':
111 if(repeat_count<2)
112 result += pad_int(dt.day,2);
113 break;
114 case 'D':
115 if(repeat_count==1)
116 result += StringFormat("%02d/%02d/%02d", dt.mon, dt.day, (int)(dt.year%100));
117 else if(repeat_count==2)
118 result += pad_int(dt.day,2);
119 break;
120 case 'e':
121 if(repeat_count==1)
122 result += StringFormat("%2d", dt.day);
123 break;
124 case 'F':
125 if(repeat_count==1)
126 result += StringFormat("%lld-%02d-%02d", dt.year, dt.mon, dt.day);
127 break;
128 case 'j':
129 if(repeat_count==1)
130 result += pad_int(day_of_year(ts),3);
131 break;
132 case 'k':
133 if(repeat_count==1)
134 result += StringFormat("%2d", dt.hour);
135 break;
136 case 'l':
137 if(repeat_count==1)
138 result += StringFormat("%2d", hour24_to_12(dt.hour));
139 break;
140 case 'm':
141 if(repeat_count==1)
142 result += pad_int(dt.mon,2);
143 else if(repeat_count==2)
144 result += pad_int(dt.min,2);
145 break;
146 case 'M':
147 if(repeat_count==1)
148 result += pad_int(dt.min,2);
149 else if(repeat_count==2)
150 result += pad_int(dt.mon,2);
151 else if(repeat_count==3)
152 result += to_str((Month)dt.mon, UPPERCASE_NAME);
153 break;
154 case 'n':
155 result += "\n";
156 break;
157 case 'p':
158 result += dt.hour<12?"AM":"PM";
159 break;
160 case 'P':
161 result += dt.hour<12?"am":"pm";
162 break;
163 case 'r':
164 if(repeat_count==1)
165 result += StringFormat("%02d:%02d:%02d %s", hour24_to_12(dt.hour), dt.min, dt.sec, dt.hour<12?"AM":"PM");
166 break;
167 case 'R':
168 if(repeat_count==1)
169 result += StringFormat("%02d:%02d", dt.hour, dt.min);
170 break;
171 case 's':
172 if(repeat_count==1)
173 result += IntegerToString(ts);
174 else if(repeat_count==3)
175 result += IntegerToString(dt.ms);
176 break;
177 case 'S':
178 if(repeat_count<=2)
179 result += pad_int(dt.sec,2);
180 if(repeat_count==3)
181 result += IntegerToString(dt.ms);
182 break;
183 case 't':
184 if(repeat_count<=1)
185 result += "\t";
186 break;
187 case 'T':
188 if(repeat_count==1)
189 result += StringFormat("%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
190 break;
191 case 'u':
192 if(repeat_count==1) {
193 int dw = day_of_week(dt.year, dt.mon, dt.day);
194 if(dw==0) dw=7;
195 result += IntegerToString(dw);
196 }
197 break;
198 case 'w':
199 if(repeat_count==1)
200 result += IntegerToString(day_of_week(dt.year, dt.mon, dt.day));
201 else if(repeat_count==3)
202 result += to_str(day_of_week(dt.year, dt.mon, dt.day), SHORT_NAME);
203 break;
204 case 'W':
205 if(repeat_count==3)
206 result += to_str(day_of_week(dt.year, dt.mon, dt.day), UPPERCASE_NAME);
207 break;
208 case 'y':
209 if(repeat_count==1)
210 result += IntegerToString(dt.year%100);
211 break;
212 case 'Y':
213 if(repeat_count==1)
214 result += IntegerToString(dt.year);
215 break;
216 case 'z':
217 if(repeat_count==1) {
218 TimeZoneStruct tz = to_time_zone_struct(utc_offset);
219 string sign = tz.is_positive?"+":"-";
220 result += sign+pad_int(tz.hour,2)+pad_int(tz.min,2);
221 }
222 break;
223 case 'Z':
224 result += "UTC";
225 break;
226 }
227 }
228
238 string to_string(string format_str, long timestamp, int utc_offset=0) {
239 string result="";
240 if(StringLen(format_str)==0) return result;
242 bool is_command=false;
243 int repeat_count=0;
244 char last_char = (char)format_str[0];
245 if(last_char!='%') result+=CharToString(last_char);
246 for(int i=0;i<StringLen(format_str);++i) {
247 char current_char = (char)format_str[i];
248 if(!is_command) {
249 if(current_char=='%') {
250 ++repeat_count;
251 if(repeat_count==2) {
252 result += "%";
253 repeat_count=0;
254 }
255 continue;
256 }
257 if(!repeat_count) {
258 result += CharToString(current_char);
259 continue;
260 }
261 last_char=current_char;
262 is_command=true;
263 continue;
264 }
265 if(last_char==current_char) {
266 ++repeat_count;
267 continue;
268 }
269 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
270 repeat_count=0;
271 is_command=false;
272 --i;
273 }
274 if(is_command)
275 process_format_impl(last_char, repeat_count, timestamp, utc_offset, dt, result);
276 return result;
277 }
278
281 string to_str(string format_str, long timestamp, int utc_offset=0) {
282 return to_string(format_str, timestamp, utc_offset);
283 }
284
293 string to_string_ms(string format_str, long timestamp_ms, int utc_offset=0) {
294 string result="";
295 if(StringLen(format_str)==0) return result;
297 bool is_command=false;
298 int repeat_count=0;
299 char last_char = (char)format_str[0];
300 if(last_char!='%') result+=CharToString(last_char);
301 for(int i=0;i<StringLen(format_str);++i) {
302 char current_char = (char)format_str[i];
303 if(!is_command) {
304 if(current_char=='%') {
305 ++repeat_count;
306 if(repeat_count==2) {
307 result += "%";
308 repeat_count=0;
309 }
310 continue;
311 }
312 if(!repeat_count) {
313 result += CharToString(current_char);
314 continue;
315 }
316 last_char=current_char;
317 is_command=true;
318 continue;
319 }
320 if(last_char==current_char) {
321 ++repeat_count;
322 continue;
323 }
324 process_format_impl(last_char, repeat_count, ms_to_sec(timestamp_ms), utc_offset, dt, result);
325 repeat_count=0;
326 is_command=false;
327 --i;
328 }
329 if(is_command)
330 process_format_impl(last_char, repeat_count, ms_to_sec(timestamp_ms), utc_offset, dt, result);
331 return result;
332 }
333
336 string to_str_ms(string format_str, long timestamp_ms, int utc_offset=0) {
337 return to_string_ms(format_str, timestamp_ms, utc_offset);
338 }
339
340 //----------------------------------------------------------------------
341 // ISO8601 helpers
342 //----------------------------------------------------------------------
343
347 string to_iso8601(long ts) {
349 return StringFormat("%lld-%02d-%02dT%02d:%02d:%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
350 }
351
355 string to_iso8601_ms(long ts_ms) {
357 return StringFormat("%lld-%02d-%02dT%02d:%02d:%02d.%03d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
358 }
359
363 string to_iso8601_date(long ts) {
365 return StringFormat("%lld-%02d-%02d", dt.year, dt.mon, dt.day);
366 }
367
371 string to_iso8601_time(long ts) {
373 return StringFormat("%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
374 }
375
381 return StringFormat("%02d:%02d:%02d.%03d", dt.hour, dt.min, dt.sec, dt.ms);
382 }
383
387 string to_iso8601_utc(long ts) {
388 return to_iso8601(ts)+"Z";
389 }
390
395 return to_iso8601_ms(ts_ms)+"Z";
396 }
397
402 string to_iso8601(long ts, int utc_offset) {
403 TimeZoneStruct tz = to_time_zone(utc_offset);
404 string sign = tz.is_positive?"+":"-";
405 return StringFormat("%s%s%.2d:%.2d", to_iso8601(ts), sign, tz.hour, tz.min);
406 }
407
412 string to_iso8601_ms(long ts_ms, int utc_offset) {
413 TimeZoneStruct tz = to_time_zone(utc_offset);
414 string sign = tz.is_positive?"+":"-";
415 return StringFormat("%s%s%.2d:%.2d", to_iso8601_ms(ts_ms), sign, tz.hour, tz.min);
416 }
417
418 //----------------------------------------------------------------------
419 // MQL5 specific helpers
420 //----------------------------------------------------------------------
421
425 string to_mql5_date_time(long ts) {
427 return StringFormat("%lld.%02d.%02d %02d:%02d:%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
428 }
429
433 string to_mql5_date(long ts) {
435 return StringFormat("%lld.%02d.%02d", dt.year, dt.mon, dt.day);
436 }
437
441 string to_mql5_time(long ts) {
443 return StringFormat("%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
444 }
445
448 string to_mql5_full(long ts) { return to_mql5_date_time(ts); }
449
453 string to_windows_filename(long ts) {
455 return StringFormat("%lld-%02d-%02d_%02d-%02d-%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
456 }
457
463 return StringFormat("%lld-%02d-%02d_%02d-%02d-%02d-%03d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
464 }
465
469 string to_human_readable(long ts) {
471 return StringFormat("%lld-%02d-%02d %02d:%02d:%02d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec);
472 }
473
479 return StringFormat("%lld-%02d-%02d %02d:%02d:%02d.%03d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
480 }
481
483
484}; // namespace time_shield
485
486#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.
@ SHORT_NAME
Short name.
Definition enums.hpp:20
@ FULL_NAME
Full name.
Definition enums.hpp:21
@ UPPERCASE_NAME
Uppercase short name.
Definition enums.hpp:19
TIME_SHIELD_CONSTEXPR ts_t timestamp(year_t year, int month, int day)
Alias for to_timestamp.
const T to_time_zone(tz_t offset)
Converts an integer to a time zone structure.
T to_date_time_ms(ts_ms_t ts)
Converts a timestamp in milliseconds to a date-time structure with milliseconds.
constexpr ts_ms_t timestamp_ms(year_t year, int month, int day)
Alias for to_timestamp_ms.
TIME_SHIELD_CONSTEXPR ts_t ts(year_t year, int month, int day)
Alias for to_timestamp.
constexpr const T1 day_of_week(year_t year, int month, int day)
Alias for day_of_week_date.
TIME_SHIELD_CONSTEXPR const T hour24_to_12(T hour) noexcept
Converts a 24-hour format hour to a 12-hour format.
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 T day_of_year(ts_t ts=time_shield::ts())
Get the day of the year.
constexpr const T1 ms_to_sec(T2 ts_ms) noexcept
Converts a timestamp from milliseconds to seconds.
const std::string & to_str(Weekday value, FormatType format=UPPERCASE_NAME)
Converts a Weekday enum value to a string.
Definition enums.hpp:69
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.
const TimeZoneStruct to_time_zone_struct(tz_t offset)
Converts an integer to a TimeZoneStruct.
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).