7#ifndef __TIME_SHIELD_TIME_PARSER_MQH__
8#define __TIME_SHIELD_TIME_PARSER_MQH__
19#property copyright "Copyright 2025, NewYaroslav"
20#property link "https://github.com/NewYaroslav/time-shield-cpp"
40 if(StringLen(month)==0)
42 string month_copy = month;
44 StringConcatenate(tmp,
45 StringToUpper(StringSubstr(month_copy,0,1)),
46 StringToLower(StringSubstr(month_copy,1)));
48 static const string short_names[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
49 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
50 static const string full_names[] = {
"January",
"February",
"March",
"April",
"May",
"June",
51 "July",
"August",
"September",
"October",
"November",
"December"};
54 if(month_copy==short_names[i] || month_copy==full_names[i])
89 return ch==
' ' || ch==
'\t' || ch==
'\n' || ch==
'\r' || ch==
'\f' || ch==
'\v';
93 return ch>=
'0' && ch<=
'9';
97 return (ch>=
'A' && ch<=
'Z') || (ch>=
'a' && ch<=
'z');
101 if(ch>=
'A' && ch<=
'Z')
102 return ch -
'A' +
'a';
108 int end = StringLen(value);
113 return StringSubstr(value, begin, end - begin);
117 const int len = StringLen(value);
118 if(len != StringLen(literal))
121 for(
int i = 0; i < len; ++i) {
132 const int len = StringLen(trimmed);
133 const string k_max_long =
"9223372036854775807";
138 for(
int i = 0; i < len; ++i) {
143 if(len > StringLen(k_max_long))
145 if(len == StringLen(k_max_long) && StringCompare(trimmed, k_max_long) > 0)
148 for(
int i = 0; i < len; ++i)
149 out = out * 10 + (
long)(StringGetCharacter(trimmed, i) -
'0');
155 const long k_max_long = 9223372036854775807;
157 if(lhs <= 0 || rhs <= 0)
159 if(lhs > k_max_long / rhs)
166 const string normalized = StringToLower(unit);
168 if(normalized ==
"s") { unit_seconds = 1;
return true; }
169 if(normalized ==
"m") { unit_seconds =
SEC_PER_MIN;
return true; }
170 if(normalized ==
"h") { unit_seconds =
SEC_PER_HOUR;
return true; }
171 if(normalized ==
"d") { unit_seconds =
SEC_PER_DAY;
return true; }
172 if(normalized ==
"w") { unit_seconds = 7 *
SEC_PER_DAY;
return true; }
173 if(normalized ==
"mn") { unit_seconds = 30 *
SEC_PER_DAY;
return true; }
174 if(normalized ==
"q") { unit_seconds = 90 *
SEC_PER_DAY;
return true; }
175 if(normalized ==
"y") { unit_seconds =
SEC_PER_YEAR;
return true; }
180 const string normalized = StringToLower(unit);
182 if(normalized ==
"sec" || normalized ==
"second" || normalized ==
"seconds") { unit_seconds = 1;
return true; }
183 if(normalized ==
"min" || normalized ==
"minute" || normalized ==
"minutes") { unit_seconds =
SEC_PER_MIN;
return true; }
184 if(normalized ==
"hr" || normalized ==
"hour" || normalized ==
"hours") { unit_seconds =
SEC_PER_HOUR;
return true; }
185 if(normalized ==
"day" || normalized ==
"days") { unit_seconds =
SEC_PER_DAY;
return true; }
186 if(normalized ==
"week" || normalized ==
"weeks") { unit_seconds = 7 *
SEC_PER_DAY;
return true; }
187 if(normalized ==
"month" || normalized ==
"months") { unit_seconds = 30 *
SEC_PER_DAY;
return true; }
188 if(normalized ==
"quarter" || normalized ==
"quarters") { unit_seconds = 90 *
SEC_PER_DAY;
return true; }
189 if(normalized ==
"year" || normalized ==
"years") { unit_seconds =
SEC_PER_YEAR;
return true; }
196 const int len = StringLen(str);
201 long unit_seconds = 0;
203 const int first = StringGetCharacter(str, 0);
218 string unit = StringSubstr(str, pos);
219 for(
int i = 0; i < StringLen(unit); ++i) {
240 string unit = StringSubstr(str, 0, pos);
244 seconds = unit_seconds;
251 for(
int i = pos; i < len; ++i) {
275 if(StringLen(tz_str)==0 || tz_str==
"Z")
280 tz.
hour = (int)StringToInteger(StringSubstr(tz_str,1,2));
281 tz.
min = (int)StringToInteger(StringSubstr(tz_str,4,2));
300 string date_part=input_str;
302 int posT=StringFind(input_str,
"T");
303 if (posT<0) posT=StringFind(input_str,
" ");
305 date_part=StringSubstr(input_str,0,posT);
306 time_part=StringSubstr(input_str,posT+1);
310 int cnt = StringSplit(date_part,
'-',parts);
312 cnt = StringSplit(date_part,
'/',parts);
313 if (cnt<3) cnt = StringSplit(date_part,
'.',parts);
315 if (cnt<3)
return false;
316 dt.
year=(long)StringToInteger(parts[0]);
317 dt.
mon =(int)StringToInteger(parts[1]);
318 dt.
day =(int)StringToInteger(parts[2]);
323 if (StringLen(time_part)>0) {
325 int zpos = StringFind(time_part,
"Z");
326 int ppos = StringFind(time_part,
"+");
327 int npos = StringFind(time_part,
"-");
329 if (zpos >= 0){ tzpos=zpos; tz_str=StringSubstr(time_part,zpos); }
330 else if(ppos >= 0){ tzpos=ppos; tz_str=StringSubstr(time_part,ppos); }
331 else if(npos > 0){ tzpos=npos; tz_str=StringSubstr(time_part,npos); }
332 if (tzpos >= 0) time_part=StringSubstr(time_part,0,tzpos);
335 int tcnt=StringSplit(time_part,
':',tparts);
338 dt.
hour = (int)StringToInteger(tparts[0]);
339 dt.
min = (int)StringToInteger(tparts[1]);
341 string sec_part=tparts[2];
342 int dot = StringFind(sec_part,
".");
344 dt.
sec = (int)StringToInteger(StringSubstr(sec_part,0,dot));
345 dt.
ms = (int)StringToInteger(StringSubstr(sec_part,dot+1));
347 dt.
sec = (int)StringToInteger(sec_part);
350 if (StringLen(tz_str)>0) {
586 long ts(
string str) {
673 const int k = StringSplit(str,
':', result);
678 int h = 0, m = 0, s = 0;
680 h = (int)StringToInteger(result[0]);
681 if (k > 1) m = (int)StringToInteger(result[1]);
682 if (k > 2) s = (int)StringToInteger(result[2]);
Header file with time-related constants.
Header for date and time structure and related functions (MQL5).
Header file with enumerations for weekdays, months, and other time-related categories.
constexpr int64_t ERROR_TIMESTAMP
Error timestamp value.
constexpr int64_t SEC_PER_YEAR
Seconds per year (365 days).
const int64_t MONTHS_PER_YEAR
Months per year.
constexpr int64_t SEC_PER_HOUR
Seconds per hour.
constexpr int64_t MS_PER_SEC
Milliseconds per second.
constexpr int64_t SEC_PER_DAY
Seconds per day.
constexpr int64_t SEC_PER_MIN
Seconds per minute.
TIME_SHIELD_CONSTEXPR ts_ms_t end_of_last_workday_month_ms(year_t year, int month) noexcept
Returns end-of-day millisecond timestamp for the last workday of month.
TIME_SHIELD_CONSTEXPR ts_t end_of_first_workday_month(year_t year, int month) noexcept
Returns end-of-day timestamp for the first workday of month.
TIME_SHIELD_CONSTEXPR bool workday(ts_t ts) noexcept
Alias for is_workday(ts_t).
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_first_workday_month_ms(year_t year, int month) noexcept
Returns start-of-day millisecond timestamp for the first workday of month.
TIME_SHIELD_CONSTEXPR ts_t ts(year_t year, int month, int day)
Alias for to_timestamp.
TIME_SHIELD_CONSTEXPR ts_t end_of_last_workday_month(year_t year, int month) noexcept
Returns end-of-day timestamp for the last workday of month.
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_last_workday_month_ms(year_t year, int month) noexcept
Returns start-of-day millisecond timestamp for the last workday of month.
TIME_SHIELD_CONSTEXPR bool workday_ms(ts_ms_t ts_ms) noexcept
Alias for is_workday(ts_ms_t).
TIME_SHIELD_CONSTEXPR ts_t start_of_last_workday_month(year_t year, int month) noexcept
Returns start-of-day timestamp for the last workday of month.
TIME_SHIELD_CONSTEXPR T1 sec_to_ms(T2 ts) noexcept
Converts a timestamp from seconds to milliseconds.
TIME_SHIELD_CONSTEXPR ts_ms_t end_of_first_workday_month_ms(year_t year, int month) noexcept
Returns end-of-day millisecond timestamp for the first workday of month.
TIME_SHIELD_CONSTEXPR ts_t start_of_first_workday_month(year_t year, int month) noexcept
Returns start-of-day timestamp for the first workday of month.
bool timeframe_try_multiply_positive_long(long lhs, long rhs, long &out)
bool timeframe_is_ascii_alpha(const int ch)
bool parse_iso8601(const char *input, std::size_t length, DateTimeStruct &dt, TimeZoneStruct &tz) noexcept
Parse ISO8601 character buffer into DateTimeStruct and TimeZoneStruct.
bool timeframe_try_parse_positive_long(string value, long &out)
bool is_last_workday_of_month(const std::string &str)
Parse an ISO8601 string and check if it is the last workday of its month (seconds).
bool str_to_ts_ms(const std::string &str, ts_ms_t &ts)
Convert an ISO8601 string to a millisecond timestamp (ts_ms_t).
bool is_within_last_workdays_of_month_ms(const std::string &str, int count)
Parse ISO8601 string and check if it is within last N workdays of its month (milliseconds).
bool timeframe_try_parse_seconds(string str, long &seconds)
int timeframe_ascii_to_lower(const int ch)
bool parse_time_zone(const char *data, std::size_t length, TimeZoneStruct &tz) noexcept
Parse timezone character buffer into TimeZoneStruct.
bool timeframe_try_get_unit_seconds_compact(string unit, long &unit_seconds)
bool is_first_workday_of_month_ms(const std::string &str)
Parse an ISO8601 string and check if it is the first workday of its month (millisecond precision).
bool try_get_month_number(const std::string &month, T &value)
Try get the month number by name, with output parameter.
bool str_to_timeframe_ms(const std::string &str, ts_ms_t &milliseconds) noexcept
Parse timeframe string into fixed milliseconds.
bool timeframe_is_ascii_space(const int ch)
bool is_within_first_workdays_of_month_ms(const std::string &str, int count)
Parse an ISO8601 string and check if it falls within the first N workdays of its month (millisecond p...
bool is_workday(const std::string &str)
Parse ISO8601 string and check if it falls on a workday (seconds precision).
bool timeframe_ascii_iequals(string value, string literal)
bool sec_of_day(const std::string &str, T &sec)
Parse time of day string to seconds of day.
bool is_last_workday_of_month_ms(const std::string &str)
Parse an ISO8601 string and check if it is the last workday of its month (millisecond).
bool str_to_timeframe_sec(const std::string &str, ts_t &seconds) noexcept
Parse timeframe string into fixed seconds.
bool timeframe_try_get_unit_seconds_word(string unit, long &unit_seconds)
string timeframe_trim_ascii(string value)
bool parse_tz(const std::string &tz_str, TimeZoneStruct &tz) noexcept
Alias for parse_time_zone.
bool timeframe_is_ascii_digit(const int ch)
bool is_within_first_workdays_of_month(const std::string &str, int count)
Parse an ISO8601 string and check if it falls within the first N workdays of its month.
bool is_first_workday_of_month(const std::string &str)
Parse ISO8601 string and check if it is the first workday of its month (seconds).
T get_month_number(const std::string &month)
Get the month number by name (throwing).
bool str_to_ts(const std::string &str, ts_t &ts)
Convert an ISO8601 string to a timestamp (ts_t).
bool str_to_fts(const std::string &str, fts_t &ts)
Convert an ISO8601 string to a floating-point timestamp (fts_t).
ts_t timeframe_sec(const std::string &str) noexcept
Convert timeframe string to fixed seconds.
ts_ms_t timeframe_ms(const std::string &str) noexcept
Convert timeframe string to fixed milliseconds.
bool is_within_last_workdays_of_month(const std::string &str, int count)
Parse ISO8601 string and check if it is within last N workdays of its month (seconds).
bool is_workday_ms(const std::string &str)
Parse ISO8601 string and check if it falls on a workday (milliseconds precision).
TIME_SHIELD_CONSTEXPR tz_t to_offset(const TimeZoneStruct &tz) noexcept
Alias for time_zone_struct_to_offset.
TIME_SHIELD_CONSTEXPR T month_of_year(ts_t ts) noexcept
Get the month of the year.
TIME_SHIELD_CONSTEXPR fts_t to_ftimestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0)
Converts a date and time to a floating-point timestamp.
TIME_SHIELD_CONSTEXPR ts_t to_timestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0)
Converts a date and time to a timestamp.
const DateTimeStruct create_date_time_struct(int64_t year, int mon=1, int day=1, int hour=0, int min=0, int sec=0, int ms=0)
Creates a DateTimeStruct instance.
TimeZoneStruct create_time_zone_struct(int hour, int min, bool is_positive=true)
Creates a TimeZoneStruct instance.
TIME_SHIELD_CONSTEXPR ts_ms_t to_timestamp_ms(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T2 ms=0)
Converts a date-time structure to a timestamp in milliseconds.
ts_t ts() noexcept
Get the current UTC timestamp in seconds.
ts_ms_t ts_ms() noexcept
Get the current UTC timestamp in milliseconds.
fts_t fts() noexcept
Get the current UTC timestamp in floating-point seconds.
TIME_SHIELD_CONSTEXPR bool is_valid_time_zone(T hour, T min) noexcept
Check if the time zone is valid.
TIME_SHIELD_CONSTEXPR bool is_valid_date(T1 year, T2 month, T2 day) noexcept
Checks the correctness of the specified date.
TIME_SHIELD_CONSTEXPR bool is_valid_time(T1 hour, T1 min, T1 sec, T2 ms=0) noexcept
Checks the correctness of the specified time.
TIME_SHIELD_CONSTEXPR bool is_valid_date_time(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0) noexcept
Checks the correctness of a date and time.
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).
Header with validation functions for dates, times, and timestamps.