//+------------------------------------------------------------------+ //| TimeUtils.mqh | //| Copyright © 2026, Amr Ali | //| https://www.mql5.com/en/users/amrali | //+------------------------------------------------------------------+ #property copyright "Copyright © 2026, Amr Ali" #property link "https://www.mql5.com/en/users/amrali" #property version "2.55" #property description "High-performance functions for dealing with time." // Updates: // 2024.12.03 - v1.10 : Initial release. // 2024.12.05 - v1.15 : Added functions for business days and for Nth() weekday of the month. Optimized calculations in DaysInMonth() function. // 2024.12.09 - v1.20 : Added TimeFormat() function to format the time according to the passed string of tokens. // 2024.12.09 - v1.25 : Optimized calculations in TimeToStructFast() function. // 2024.12.10 - v1.30 : Optimized TimeFormat(), StartOfYear() and EndOfYear() functions. Updated descriptions of some functions. // 2024.12.15 - v1.35 : Optimized NthWeekdayOfYearMonth() function. // 2024.12.18 - v1.40 : Added IsCurrentXXX(), IsToday(), IsTomorrow() and IsYesterday() functions. // 2024.12.19 - v1.45 : Optimized AddMonths() and NthWeekdayOfYearMonth() functions. // 2024.12.20 - v1.50 : More code clean-up. // 2024.12.21 - v1.55 : Simplified calculations in AddMonths(): replaced the complex logic of adjusting months and years with a simpler total months calculation. // 2026.06.22 - v1.60 : Optimized AddBusinessDays() and DifferenceInBusinessDays() functions. Added various IsXXX() check functions. // 2026.07.06 - v2.00 : New March-based conversion routines derived from the Neri–Schneider calendar algorithm + validation script. Removed "performance" mode. // 2026.07.07 - v2.10 : Added DaysInYear(), LastDayOf(), MinuteOf(), HourOf() and CalendarDifferenceToString() functions. // 2026.07.10 - v2.30 : Added date construction, quarter, calendar difference, and relative-date helper functions. Introduced configurable week start and renamed several functions for a cleaner, more consistent API. // 2026.07.12 - v2.35 : Updated CalendarDifferenceToString() to return the precise elapsed time, including hours, minutes, and seconds. // 2026.07.14 - v2.40 : Redesigned the year/month decomposition in CalendarDifferenceToString() to correctly handle February 29 edge cases. Simplified and optimized the DifferenceInXXX() functions. Added epoch-based index functions. // 2026.07.15 - v2.45 : Added CalendarDifference() to return the calendar difference between two dates, broken down into years, months, days, hours, minutes, and seconds. // 2026.07.18 - v2.50 : Added AddPeriod() and SubPeriod() for calendar period arithmetic. Added WithXxx() functions for replacing individual date/time fields. Added IsInSession() for checking recurring daily sessions. // 2026.07.20 - v2.55 : Optimized week-based functions. Added SessionOverlap() for calculating overlapping time intervals. Improved documentation and API comments. #ifdef __MQL4__ #property strict #endif #ifndef TIMEUTILS_UNIQUE_HEADER_ID_H #define TIMEUTILS_UNIQUE_HEADER_ID_H // First day of the week used by all week-related functions. // Optionally, override the default before including this header: // // #define TIMEUTILS_FIRST_DAY_OF_WEEK SUNDAY // #include "TimeUtils.mqh" // // Valid values: SUNDAY or MONDAY (default: MONDAY). #ifndef TIMEUTILS_FIRST_DAY_OF_WEEK #define TIMEUTILS_FIRST_DAY_OF_WEEK MONDAY #endif //#################################################################### //# # //# Construction & Conversion # //# # //#################################################################### //DateFrom(2026, 7, 20) //DateFromString("2026.07.20 14:30") //TimeToStructFast(datetime, MqlDateTime) //StructToTimeFast(MqlDateTime) //#################################################################### //# # //# Calendar Fields & Components # //# # //#################################################################### //+==================================================================+ //| Calendar Fields | //+==================================================================+ // Year(datetime) Month(datetime) // Day(datetime) Hour(datetime) // Minute(datetime) Second(datetime) // DayOfWeek(datetime) datetime DateOnly(tm) // DayOfYear(datetime) datetime TimeOnly(tm) //#################################################################### //# # //# Calendar Indices & Positions # //# # //#################################################################### //+==================================================================+ //| Absolute Indices | //+==================================================================+ // YearIndex(datetime) MonthIndex(datetime) // QuarterIndex(datetime) WeekIndex(datetime) // DayIndex(datetime) HourIndex(datetime) // MinuteIndex(datetime) //+==================================================================+ //| Position Within Calendar | //+==================================================================+ // Quarter(datetime) // WeekOfYear(datetime) WeekOfMonth(datetime) // HourOfYear(datetime) MinuteOfYear(datetime) // HourOfQuarter(datetime) MinuteOfQuarter(datetime) // HourOfMonth(datetime) MinuteOfMonth(datetime) // HourOfWeek(datetime) MinuteOfWeek(datetime) // MinuteOfDay(datetime) // SecsElapsedOfYear(datetime) SecsElapsedOfQuarter(datetime) // SecsElapsedOfMonth(datetime) SecsElapsedOfWeek(datetime) // SecsElapsedOfDay(datetime) SecsElapsedOfHour(datetime) // SecsElapsedOfMinute(datetime) SecsElapsedOfEpoch(datetime) // SecondsSinceMidnight(datetime) //#################################################################### //# # //# Navigation / Manipulation # //# # //#################################################################### //+==================================================================+ //| Period Boundaries | //+==================================================================+ // datetime StartOfMinute(datetime) datetime EndOfMinute(datetime) // datetime StartOfHour(datetime) datetime EndOfHour(datetime) // datetime StartOfDay(datetime) datetime EndOfDay(datetime) // datetime StartOfWeek(datetime) datetime EndOfWeek(datetime) // datetime StartOfMonth(datetime) datetime EndOfMonth(datetime) // datetime StartOfQuarter(datetime) datetime EndOfQuarter(datetime) // datetime StartOfYear(datetime) datetime EndOfYear(datetime) // datetime StartOfToday() datetime EndOfToday() // datetime StartOfTomorrow() datetime EndOfTomorrow() // datetime StartOfYesterday() datetime EndOfYesterday() //+==================================================================+ //| Calendar Navigation | //+==================================================================+ // datetime LastDayOfWeek(datetime) datetime FirstWeekdayOfMonth(datetime, MONDAY) // datetime LastDayOfMonth(datetime) datetime LastWeekdayOfMonth(datetime, FRIDAY) // datetime LastDayOfQuarter(datetime) datetime NthWeekdayOfYearMonth(2026, 11, Nth, FRIDAY) // datetime LastDayOfYear(datetime) // datetime NextDayOfWeek(datetime, MONDAY) datetime PreviousDayOfWeek(datetime, MONDAY) // datetime NextSunday(datetime) datetime PreviousSunday(datetime) // datetime NextMonday(datetime) datetime PreviousMonday(datetime) // datetime NextTuesday(datetime) datetime PreviousTuesday(datetime) // datetime NextWednesday(datetime) datetime PreviousWednesday(datetime) // datetime NextThursday(datetime) datetime PreviousThursday(datetime) // datetime NextFriday(datetime) datetime PreviousFriday(datetime) // datetime NextSaturday(datetime) datetime PreviousSaturday(datetime) //+==================================================================+ //| Rounding & Alignment | //+==================================================================+ // datetime RoundToMinute(datetime) datetime CeilToMinute(datetime) // datetime RoundToHour(datetime) datetime CeilToHour(datetime) // datetime RoundToDay(datetime) datetime CeilToDay(datetime) // datetime RoundToWeek(datetime) datetime CeilToWeek(datetime) //+==================================================================+ //| Field Replacement | //+==================================================================+ // datetime WithSecond(datetime, 30) datetime WithMonth(datetime, 12) // datetime WithMinute(datetime, 45) datetime WithYear(datetime, 2030) // datetime WithHour(datetime, 14) datetime WithTime(datetime, 14, 30, 0) // datetime WithDay(datetime, 15) datetime WithDate(datetime, 2026, 7, 20) // datetime WithDayOfWeek(datetime, FRIDAY) //+==================================================================+ //| Arithmetic | //+==================================================================+ // datetime AddSeconds(datetime, 30) datetime SubSeconds(datetime, 30) // datetime AddMinutes(datetime, 15) datetime SubMinutes(datetime, 15) // datetime AddHours(datetime, 8) datetime SubHours(datetime, 8) // datetime AddDays(datetime, 5) datetime SubDays(datetime, 5) // datetime AddBusinessDays(datetime, 5) datetime SubBusinessDays(datetime, 5) // datetime AddWeeks(datetime, 2) datetime SubWeeks(datetime, 2) // datetime AddMonths(datetime, 3) datetime SubMonths(datetime, 3) // datetime AddQuarters(datetime, 2) datetime SubQuarters(datetime, 2) // datetime AddYears(datetime, 10) datetime SubYears(datetime, 10) // datetime AddPeriod(datetime, MqlDateTime period) // datetime SubPeriod(datetime, MqlDateTime period) //#################################################################### //# # //# Differences & Duration # //# # //#################################################################### //+==================================================================+ //| Exact Time Durations | //+==================================================================+ // DifferenceInSeconds(from, to) DifferenceInBusinessDays(from, to) // DifferenceInMinutes(from, to) DifferenceInWeekendDays(from, to) // DifferenceInHours(from, to) // DifferenceInDays(from, to) // DifferenceInWeeks(from, to) // DifferenceInMonths(from, to) // DifferenceInQuarters(from, to) // DifferenceInYears(from, to) //+==================================================================+ //| Calendar Differences | //+==================================================================+ // DifferenceInCalendarDays(from, to) DifferenceInCalendarWeeks(from, to) // DifferenceInCalendarMonths(from, to) DifferenceInCalendarQuarters(from, to) // DifferenceInCalendarYears(from, to) // CalendarDifference(from, to, MqlDateTime period) // CalendarDifferenceToString(from, to) //#################################################################### //# # //# Validation & Comparison # //# # //#################################################################### //+==================================================================+ //| Day Checks | //+==================================================================+ // IsWeekday(datetime) IsWeekend(datetime) // IsSunday(datetime) IsThursday(datetime) // IsMonday(datetime) IsFriday(datetime) // IsTuesday(datetime) IsSaturday(datetime) // IsWednesday(datetime) // IsFirstDayOfMonth(datetime) IsToday(datetime) // IsLastDayOfMonth(datetime) IsTomorrow(datetime) // IsYesterday(datetime) //+==================================================================+ //| Current Period | //+==================================================================+ // IsCurrentMinute(datetime) IsCurrentMonth(datetime) // IsCurrentHour(datetime) IsCurrentQuarter(datetime) // IsCurrentWeek(datetime) IsCurrentYear(datetime) //+==================================================================+ //| Equality | //+==================================================================+ // IsSameMinute(a, b) IsSameMonth(a, b) // IsSameHour(a, b) IsSameQuarter(a, b) // IsSameDay(a, b) IsSameYear(a, b) // IsSameWeek(a, b) //+==================================================================+ //| Daily Trading Sessions | //+==================================================================+ // IsInSession(datetime, IsInSession("08:00", "17:00") // 8, 0, 17, 0) // IsInSession(8, 0, 17, 0) bool SessionOverlap() //#################################################################### //# # //# Calendar Information # //# # //#################################################################### // DaysInMonth(2026, 7) WeeksInMonth(2026, 7) // DaysInYear(2026) WeeksInYear(2026) // IsLeapYear(2028) //#################################################################### //# # //# Formatting & Utilities # //# # //#################################################################### // DayName(ENUM_DAY_OF_WEEK) // MonthName(7) // SecondsToString(3661) // t2s(datetime, TIME_DATE | TIME_MINUTES) // TimeFormat(datetime, "YYYY.MM.DD hh:mm") //+------------------------------------------------------------------+ //| Time unit conversion constants | //+------------------------------------------------------------------+ #define MINSECS 60ULL #define HOURSECS 3600ULL #define DAYSECS 86400ULL #define WEEKSECS 604800ULL #define DAYS_PER_4_YEARS 1461U // (4 * 365) + 1 #define DAYS_PER_400_YEARS 146097U // DAYS_PER_4_YEARS * 100 - 3 non-leap century years. #define DAYS_TO_1970 719162 // Number of days from 1/1/0001 to 12/31/1969. #define MARCH1_BASED_DOY 306 // Number of days between March 1 and January 1. // Offset used to align calendar week boundaries. // 1970-01-01 (Unix epoch) was a Thursday. #define WEEK_OFFSET \ ((THURSDAY - (int)TIMEUTILS_FIRST_DAY_OF_WEEK) * DAYSECS) //#################################################################### //# # //# Construction # //# # //#################################################################### //+==================================================================+ //| Create datetime From Components | //+==================================================================+ //+------------------------------------------------------------------+ //| Create a datetime value from the specified date and time. | //+------------------------------------------------------------------+ datetime DateFrom(const int year, // Year const int mon, // Month const int day, // Day const int hour = 0, // Hour const int min = 0, // Minutes const int sec = 0) // Seconds { MqlDateTime dt = {year, mon, day, hour, min, sec}; return StructToTimeFast(dt); } //+------------------------------------------------------------------+ //| Create a datetime from a formatted date/time string. | //+------------------------------------------------------------------+ datetime DateFromString(const string text) { return StringToTime(text); } //+------------------------------------------------------------------+ //| Faster alternative to MQL's StructToTime() function. | //| Converts a structure variable MqlDateTime into a value of | //| datetime type and returns the resulting value containing | //| the number of seconds since 01.01.1970. | //+------------------------------------------------------------------+ datetime StructToTimeFast(const MqlDateTime& dt_struct) { const uint j = dt_struct.mon < 3; const uint y = dt_struct.year - j; const uint m = j ? dt_struct.mon + 12 : dt_struct.mon; const uint f = (979 * m - 2918) / 32; // days before month const uint n = dt_struct.day - 1 + f + 365*y + (y/4) - (y/100) + (y/400) - DAYS_TO_1970 - MARCH1_BASED_DOY; return (datetime)((n * DAYSECS) + (dt_struct.hour * HOURSECS) + (dt_struct.min * MINSECS) + dt_struct.sec); } //#################################################################### //# # //# Calendar Components # //# # //#################################################################### //+==================================================================+ //| Break datetime To Components | //+==================================================================+ //+------------------------------------------------------------------+ //| Faster alternative to MQL's TimeToStruct() function. | //| Converts a value of datetime type (number of seconds | //| since 01.01.1970) into a structure variable MqlDateTime. | //| https://github.com/cassioneri/eaf/blob/main/algorithms/neri_schneider.hpp //+------------------------------------------------------------------+ bool TimeToStructFast(const datetime time, MqlDateTime& dt_struct) { uint n = (uint)(time / DAYSECS) ; // Unix day uint N = n + 12699422 ; // Computational calendar day uint a = 4 * N + 3 ; // N_1 uint c = a / DAYS_PER_400_YEARS ; // century uint e = a % DAYS_PER_400_YEARS / 4 ; // [0, 36524] - dayOfCentury uint b = 4 * e + 3 ; // N_2 uint z = b / DAYS_PER_4_YEARS ; // [0, 99] - yearOfCentury uint h = b % DAYS_PER_4_YEARS / 4 ; // [0, 365] - Days since 1 March uint d = 2141 * h + 197913 ; // N_3 uint M = d / 65536 ; // [3, 14] - Month uint D = d % 65536 / 2141U ; // [0, 30] - Day uint Y = 100 * c + z ; // Year uint J = h >= MARCH1_BASED_DOY ; // JanFeb uint l = z ? (z % 4 == 0) : (c % 4 == 0) ; // isLeap uint seconds = (uint)(time - n * DAYSECS) ; uint minutes = seconds / 60 ; uint hours = minutes / 60 ; dt_struct.year = (int)(Y - 32800 + J) ; dt_struct.mon = (int)(J ? M - 12 : M) ; dt_struct.day = (int)(D + 1) ; dt_struct.hour = (int)(hours) ; dt_struct.min = (int)(minutes - (hours * 60)); dt_struct.sec = (int)(seconds - (minutes * 60)); dt_struct.day_of_week = (int)((n + 4) % 7U); dt_struct.day_of_year = (int)(h + (J ? -MARCH1_BASED_DOY : 59 + l)); return (true); } //+==================================================================+ //| Extract Components of datetime: Sunday, yyyy.mm.dd hh:mm:ss | //| Get() Units | //+==================================================================+ int Second(void) { return Second(TimeTradeServer()); } // gets current second (0..59) int Minute(void) { return Minute(TimeTradeServer()); } // gets current minute (0..59) int Hour(void) { return Hour(TimeTradeServer()); } // gets current hour (0..23) int Day(void) { return Day(TimeTradeServer()); } // gets day of current month (1..31) int Month(void) { return Month(TimeTradeServer()); } // gets current month (1..12) int Year(void) { return Year(TimeTradeServer()); } // gets current year (1970..3000) int DayOfWeek(void) { return DayOfWeek(TimeTradeServer()); } // gets day of current week (0..6) int DayOfYear(void) { return DayOfYear(TimeTradeServer()); } // gets day of current year (0..365) //+------------------------------------------------------------------+ //| Return seconds of minute as integer (0..59) | //+------------------------------------------------------------------+ int Second(const datetime t) { return (int)(t % MINSECS); } //+------------------------------------------------------------------+ //| Return minutes of hour as integer (0..59) | //+------------------------------------------------------------------+ int Minute(const datetime t) { return (int)((t / MINSECS) % MINSECS); } //+------------------------------------------------------------------+ //| Return hour of day as integer (0..23) | //+------------------------------------------------------------------+ int Hour(const datetime t) { return (int)((t / HOURSECS) % 24U); } //+------------------------------------------------------------------+ //| Return day of month as integer (1..31) | //+------------------------------------------------------------------+ int Day(const datetime t) { // MqlDateTime dt; // TimeToStructFast(t, dt); // return(dt.day); uint dayOfCentury = ((((uint)(t / DAYSECS) + DAYS_TO_1970 + MARCH1_BASED_DOY) << 2) | 3U) % DAYS_PER_400_YEARS; uint daySinceMarch1 = (dayOfCentury | 3U) % DAYS_PER_4_YEARS / 4; uint monthDayPacked = daySinceMarch1 * 2141 + 197913; return (int)((monthDayPacked & 0xFFFF) / 2141) + 1; } //+------------------------------------------------------------------+ //| Return the month number as integer (1..12) | //+------------------------------------------------------------------+ int Month(const datetime t) { // MqlDateTime dt; // TimeToStructFast(t, dt); // return(dt.mon); uint dayOfCentury = ((((uint)(t / DAYSECS) + DAYS_TO_1970 + MARCH1_BASED_DOY) << 2) | 3U) % DAYS_PER_400_YEARS; uint daySinceMarch1 = (dayOfCentury | 3U) % DAYS_PER_4_YEARS / 4; uint monthDayPacked = daySinceMarch1 * 2141 + 197913; return (int)(monthDayPacked >> 16) - (daySinceMarch1 >= MARCH1_BASED_DOY ? 12 : 0); } //+------------------------------------------------------------------+ //| Return the year as integer (1970..3000) | //+------------------------------------------------------------------+ int Year(const datetime t) { // MqlDateTime dt; // TimeToStructFast(t, dt); // return(dt.year); uint days = ((((uint)(t / DAYSECS) + DAYS_TO_1970) << 2) | 3U); uint century = days / DAYS_PER_400_YEARS; uint year = ((days % DAYS_PER_400_YEARS) | 3U) / DAYS_PER_4_YEARS; return (int)(100 * century + year) + 1; } //+------------------------------------------------------------------+ //| Return the date part for the given date. | //+------------------------------------------------------------------+ datetime DateOnly(const datetime t) { return StartOfDay(t); } //+------------------------------------------------------------------+ //| Return the time part for the given date. | //+------------------------------------------------------------------+ datetime TimeOnly(const datetime t) { return (datetime)SecsElapsedOfDay(t); } //+==================================================================+ //| Day() Numbering | //+==================================================================+ //+------------------------------------------------------------------+ //| Day of the week as integer (0 = Sunday to 6 = Saturday) | //+------------------------------------------------------------------+ int DayOfWeek(const datetime t) { return (int)((t / DAYSECS + THURSDAY) % 7U); // 1 Jan 1970 is Thursday } //+------------------------------------------------------------------+ //| Returns the zero-based day of the year as integer (0...365) | //+------------------------------------------------------------------+ int DayOfYear(const datetime t) { return (int)(((((((uint)(t / DAYSECS) + DAYS_TO_1970) << 2) | 3U) % DAYS_PER_400_YEARS) | 3U) % DAYS_PER_4_YEARS) >> 2; } //+==================================================================+ //| Quarter of Year | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the year quarter number (1..4). | //+------------------------------------------------------------------+ int Quarter(const datetime t) { return ((Month(t) - 1) / 3) + 1; } //+==================================================================+ //| Epoch-Based Indices | //+==================================================================+ //+------------------------------------------------------------------+ //| Returns the zero-based minute index since 1970-01-01 00:00. | //+------------------------------------------------------------------+ int MinuteIndex(const datetime t) { return (int)(t / MINSECS); } //+------------------------------------------------------------------+ //| Returns the zero-based hour index since 1970-01-01 00:00. | //+------------------------------------------------------------------+ int HourIndex(const datetime t) { return (int)(t / HOURSECS); } //+------------------------------------------------------------------+ //| Returns the zero-based day index since 1970-01-01. | //| Useful for indicators to determine the first bar of the new day: | //| bool NewDay = DayIndex(time[i]) != DayIndex(time[i-1]); | //+------------------------------------------------------------------+ int DayIndex(const datetime t) { return (int)(t / DAYSECS); } //+------------------------------------------------------------------+ //| Returns the zero-based calendar week index since the week | //| containing 1970-01-01. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int WeekIndex(const datetime t) { return (int)((t + WEEK_OFFSET) / WEEKSECS); } //+------------------------------------------------------------------+ //| Returns the zero-based calendar month index since 1970-01. | //+------------------------------------------------------------------+ int MonthIndex(const datetime t) { return (Year(t) - 1970) * 12 + Month(t) - 1; } //+------------------------------------------------------------------+ //| Returns the zero-based calendar quarter index since 1970 Q1. | //+------------------------------------------------------------------+ int QuarterIndex(const datetime t) { return (Year(t) - 1970) * 4 + Quarter(t) - 1; } //+------------------------------------------------------------------+ //| Returns the zero-based calendar year index since 1970. | //+------------------------------------------------------------------+ int YearIndex(const datetime t) { return Year(t) - 1970; } //+==================================================================+ //| HourOf() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Hours elapsed from the start of week for the given date. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int HourOfWeek(const datetime t) { return (int)(SecsElapsedOfWeek(t) / HOURSECS); } //+------------------------------------------------------------------+ //| Hours elapsed from the start of month for the given date. | //+------------------------------------------------------------------+ int HourOfMonth(const datetime t) { return (int)(SecsElapsedOfMonth(t) / HOURSECS); } //+------------------------------------------------------------------+ //| Hours elapsed from the start of quarter for the given date. | //+------------------------------------------------------------------+ int HourOfQuarter(const datetime t) { return (int)(SecsElapsedOfQuarter(t) / HOURSECS); } //+------------------------------------------------------------------+ //| Hours elapsed from the start of year for the given date. | //+------------------------------------------------------------------+ int HourOfYear(const datetime t) { return (int)(SecsElapsedOfYear(t) / HOURSECS); } //+==================================================================+ //| MinuteOf() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Minutes elapsed from the start of day for the given date. | //+------------------------------------------------------------------+ int MinuteOfDay(const datetime t) { return (int)(SecsElapsedOfDay(t) / MINSECS); } //+------------------------------------------------------------------+ //| Minutes elapsed from the start of week for the given date. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int MinuteOfWeek(const datetime t) { return (int)(SecsElapsedOfWeek(t) / MINSECS); } //+------------------------------------------------------------------+ //| Minutes elapsed from the start of month for the given date. | //+------------------------------------------------------------------+ int MinuteOfMonth(const datetime t) { return (int)(SecsElapsedOfMonth(t) / MINSECS); } //+------------------------------------------------------------------+ //| Minutes elapsed from the start of quarter for the given date. | //+------------------------------------------------------------------+ int MinuteOfQuarter(const datetime t) { return (int)(SecsElapsedOfQuarter(t) / MINSECS); } //+------------------------------------------------------------------+ //| Minutes elapsed from the start of year for the given date. | //+------------------------------------------------------------------+ int MinuteOfYear(const datetime t) { return (int)(SecsElapsedOfYear(t) / MINSECS); } //+==================================================================+ //| SecsElapsedOf() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Seconds elapsed from the start of minute for the given date. | //+------------------------------------------------------------------+ int SecsElapsedOfMinute(const datetime t) { return (int)(t % MINSECS); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of hour for the given date. | //+------------------------------------------------------------------+ int SecsElapsedOfHour(const datetime t) { return (int)(t % HOURSECS); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of day for the given date. | //+------------------------------------------------------------------+ int SecsElapsedOfDay(const datetime t) { return (int)(t % DAYSECS); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of day for the given date. | //+------------------------------------------------------------------+ int SecondsSinceMidnight(const datetime t) { return (int)(t % DAYSECS); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of week for the given date. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int SecsElapsedOfWeek(const datetime t) { return (int)((t + WEEK_OFFSET) % WEEKSECS); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of month for the given date. | //+------------------------------------------------------------------+ int SecsElapsedOfMonth(const datetime t) { return (int)(t - StartOfMonth(t)); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of quarter for the given date. | //+------------------------------------------------------------------+ int SecsElapsedOfQuarter(const datetime t) { return (int)(t - StartOfQuarter(t)); } //+------------------------------------------------------------------+ //| Seconds elapsed from the start of year for the given date. | //+------------------------------------------------------------------+ int SecsElapsedOfYear(const datetime t) { return (int)(t - StartOfYear(t)); } //+------------------------------------------------------------------+ //| Seconds elapsed since 1 Jan 1970 (Unix epoch) for the given date.| //+------------------------------------------------------------------+ long SecsElapsedOfEpoch(const datetime t) { return (long)(t); } //#################################################################### //# # //# Adjusters / Navigation # //# # //#################################################################### //+==================================================================+ //| StartOf() / FloorTo() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the start of a minute for the given date. | //+------------------------------------------------------------------+ datetime StartOfMinute(const datetime t) { return t - (t % MINSECS); } //+------------------------------------------------------------------+ //| Return the start of an hour for the given date. | //+------------------------------------------------------------------+ datetime StartOfHour(const datetime t) { return t - (t % HOURSECS); } //+------------------------------------------------------------------+ //| Return the start of a day for the given date. | //+------------------------------------------------------------------+ datetime StartOfDay(const datetime t) { return t - (t % DAYSECS); } //+------------------------------------------------------------------+ //| Returns the start of the calendar week containing the given | //| date/time. The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ datetime StartOfWeek(const datetime t) { return t - ((t + WEEK_OFFSET) % WEEKSECS); } //+------------------------------------------------------------------+ //| Return the first day of a month for the given date. | //+------------------------------------------------------------------+ datetime StartOfMonth(const datetime t) { const int y = Year(t); const int m = Month(t); return DateFrom(y, m, 1); } //+------------------------------------------------------------------+ //| Return the first day of a year quarter for the given date. | //+------------------------------------------------------------------+ datetime StartOfQuarter(const datetime t) { const int y = Year(t); const int m = Month(t); const int qMonth = ((m - 1) / 3) * 3 + 1; return DateFrom(y, qMonth, 1); } //+------------------------------------------------------------------+ //| Return the first day of a year for the given date. | //+------------------------------------------------------------------+ datetime StartOfYear(const datetime t) { const int y = Year(t); return DateFrom(y, 1, 1); } //+------------------------------------------------------------------+ //| Return the start second of today on the trade server. | //+------------------------------------------------------------------+ datetime StartOfToday(void) { return StartOfDay(TimeTradeServer()); } //+------------------------------------------------------------------+ //| Return the start second of tomorrow on the trade server. | //+------------------------------------------------------------------+ datetime StartOfTomorrow(void) { return AddDays(StartOfDay(TimeTradeServer()), 1); } //+------------------------------------------------------------------+ //| Return the start second of yesterday on the trade server. | //+------------------------------------------------------------------+ datetime StartOfYesterday(void) { return SubDays(StartOfDay(TimeTradeServer()), 1); } //+==================================================================+ //| EndOf() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the last second of a minute for the given date. | //+------------------------------------------------------------------+ datetime EndOfMinute(const datetime t) { return StartOfMinute(t) + (MINSECS - 1); } //+------------------------------------------------------------------+ //| Return the last second of an hour for the given date. | //+------------------------------------------------------------------+ datetime EndOfHour(const datetime t) { return StartOfHour(t) + (HOURSECS - 1); } //+------------------------------------------------------------------+ //| Return the last second of a day for the given date. | //+------------------------------------------------------------------+ datetime EndOfDay(const datetime t) { return StartOfDay(t) + (DAYSECS - 1); } //+------------------------------------------------------------------+ //| Return the last second of a week for the given date. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ datetime EndOfWeek(const datetime t) { return StartOfWeek(t) + (WEEKSECS - 1); } //+------------------------------------------------------------------+ //| Return the last second of a month for the given date. | //+------------------------------------------------------------------+ datetime EndOfMonth(const datetime t) { // MqlDateTime dt; // TimeToStructFast(t, dt); // dt.day = DaysInMonth(dt.year, dt.mon); // dt.hour = 23; // dt.min = 59; // dt.sec = 59; // return(StructToTimeFast(dt)); int y = Year(t); int m = Month(t); m = (m % 12) + 1; y += (m == 1); return DateFrom(y, m, 1) - 1; } //+------------------------------------------------------------------+ //| Return the last second of a year quarter for the given date. | //+------------------------------------------------------------------+ datetime EndOfQuarter(const datetime t) { return EndOfMonth(AddMonths(StartOfQuarter(t), 2)); } //+------------------------------------------------------------------+ //| Return the last second of a year for the given date. | //+------------------------------------------------------------------+ datetime EndOfYear(const datetime t) { const int y = Year(t); return DateFrom((y + 1), 1, 1) - 1; } //+------------------------------------------------------------------+ //| Return the last second of today on the trade server. | //+------------------------------------------------------------------+ datetime EndOfToday(void) { return EndOfDay(TimeTradeServer()); } //+------------------------------------------------------------------+ //| Return the last second of tomorrow on the trade server. | //+------------------------------------------------------------------+ datetime EndOfTomorrow(void) { return AddDays(EndOfDay(TimeTradeServer()), 1); } //+------------------------------------------------------------------+ //| Return the last second of yesterday on the trade server. | //+------------------------------------------------------------------+ datetime EndOfYesterday(void) { return SubDays(EndOfDay(TimeTradeServer()), 1); } //+==================================================================+ //| LastDayOf() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the last day of a week for the given date. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ datetime LastDayOfWeek(const datetime t) { return EndOfWeek(t) - (DAYSECS - 1); } //+------------------------------------------------------------------+ //| Return the last day of a month for the given date. | //+------------------------------------------------------------------+ datetime LastDayOfMonth(const datetime t) { return EndOfMonth(t) - (DAYSECS - 1); } //+------------------------------------------------------------------+ //| Return the last day of a year quarter for the given date. | //+------------------------------------------------------------------+ datetime LastDayOfQuarter(const datetime t) { return EndOfQuarter(t) - (DAYSECS - 1); } //+------------------------------------------------------------------+ //| Return the last day of a year for the given date. | //+------------------------------------------------------------------+ datetime LastDayOfYear(const datetime t) { return EndOfYear(t) - (DAYSECS - 1); } //+==================================================================+ //| RoundTo() / Nearest() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Rounds halfway the given date to the nearest minute. | //+------------------------------------------------------------------+ datetime RoundToMinute(const datetime t) { return StartOfMinute(t + MINSECS / 2); } //+------------------------------------------------------------------+ //| Rounds halfway the given date to the nearest hour. | //+------------------------------------------------------------------+ datetime RoundToHour(const datetime t) { return StartOfHour(t + HOURSECS / 2); } //+------------------------------------------------------------------+ //| Rounds halfway the given date to the nearest day. | //+------------------------------------------------------------------+ datetime RoundToDay(const datetime t) { return StartOfDay(t + DAYSECS / 2); } //+------------------------------------------------------------------+ //| Rounds halfway the given date to the nearest week. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ datetime RoundToWeek(const datetime t) { return StartOfWeek(t + WEEKSECS / 2); } //+==================================================================+ //| CeilTo() / Next() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Rounds up the given date to the next minute. | //+------------------------------------------------------------------+ datetime CeilToMinute(const datetime t) { return StartOfMinute(t + MINSECS - 1); } //+------------------------------------------------------------------+ //| Rounds up the given date to the next hour. | //+------------------------------------------------------------------+ datetime CeilToHour(const datetime t) { return StartOfHour(t + HOURSECS - 1); } //+------------------------------------------------------------------+ //| Rounds up the given date to the next day. | //+------------------------------------------------------------------+ datetime CeilToDay(const datetime t) { return StartOfDay(t + DAYSECS - 1); } //+------------------------------------------------------------------+ //| Rounds up the given date to the next week. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ datetime CeilToWeek(const datetime t) { return StartOfWeek(t + WEEKSECS - 1); } //+==================================================================+ //| Next() Weekday | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the next occurrence of a weekday after the given date. | //+------------------------------------------------------------------+ datetime NextDayOfWeek(const datetime t, const ENUM_DAY_OF_WEEK weekday = SUNDAY) { int delta = weekday - DayOfWeek(t); if (delta <= 0) delta += 7; return AddDays(StartOfDay(t), delta); } //+------------------------------------------------------------------+ //| When is the next Sunday? | //+------------------------------------------------------------------+ datetime NextSunday(const datetime t) { return NextDayOfWeek(t, SUNDAY); } //+------------------------------------------------------------------+ //| When is the next Monday? | //+------------------------------------------------------------------+ datetime NextMonday(const datetime t) { return NextDayOfWeek(t, MONDAY); } //+------------------------------------------------------------------+ //| When is the next Tuesday? | //+------------------------------------------------------------------+ datetime NextTuesday(const datetime t) { return NextDayOfWeek(t, TUESDAY); } //+------------------------------------------------------------------+ //| When is the next Wednesday? | //+------------------------------------------------------------------+ datetime NextWednesday(const datetime t) { return NextDayOfWeek(t, WEDNESDAY); } //+------------------------------------------------------------------+ //| When is the next Thursday? | //+------------------------------------------------------------------+ datetime NextThursday(const datetime t) { return NextDayOfWeek(t, THURSDAY); } //+------------------------------------------------------------------+ //| When is the next Friday? | //+------------------------------------------------------------------+ datetime NextFriday(const datetime t) { return NextDayOfWeek(t, FRIDAY); } //+------------------------------------------------------------------+ //| When is the next Saturday? | //+------------------------------------------------------------------+ datetime NextSaturday(const datetime t) { return NextDayOfWeek(t, SATURDAY); } //+==================================================================+ //| Previous() Weekday | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the previous occurrence of a weekday before the given date. | //+------------------------------------------------------------------+ datetime PreviousDayOfWeek(const datetime t, const ENUM_DAY_OF_WEEK weekday = SUNDAY) { int delta = DayOfWeek(t) - weekday; if (delta <= 0) delta += 7; return SubDays(StartOfDay(t), delta); } //+------------------------------------------------------------------+ //| When is the previous Sunday? | //+------------------------------------------------------------------+ datetime PreviousSunday(const datetime t) { return PreviousDayOfWeek(t, SUNDAY); } //+------------------------------------------------------------------+ //| When is the previous Monday? | //+------------------------------------------------------------------+ datetime PreviousMonday(const datetime t) { return PreviousDayOfWeek(t, MONDAY); } //+------------------------------------------------------------------+ //| When is the previous Tuesday? | //+------------------------------------------------------------------+ datetime PreviousTuesday(const datetime t) { return PreviousDayOfWeek(t, TUESDAY); } //+------------------------------------------------------------------+ //| When is the previous Wednesday? | //+------------------------------------------------------------------+ datetime PreviousWednesday(const datetime t) { return PreviousDayOfWeek(t, WEDNESDAY); } //+------------------------------------------------------------------+ //| When is the previous Thursday? | //+------------------------------------------------------------------+ datetime PreviousThursday(const datetime t) { return PreviousDayOfWeek(t, THURSDAY); } //+------------------------------------------------------------------+ //| When is the previous Friday? | //+------------------------------------------------------------------+ datetime PreviousFriday(const datetime t) { return PreviousDayOfWeek(t, FRIDAY); } //+------------------------------------------------------------------+ //| When is the previous Saturday? | //+------------------------------------------------------------------+ datetime PreviousSaturday(const datetime t) { return PreviousDayOfWeek(t, SATURDAY); } //+==================================================================+ //| Nth() Weekday | //+==================================================================+ //+------------------------------------------------------------------+ //| Return the Nth weekday of the given year and month. | //| | //| Nth > 0 : 1 = first, 2 = second, ... | //| Nth < 0 : -1 = last, -2 = second last, ... | //| Returns 0 if the requested occurrence does not exist. | //+------------------------------------------------------------------+ datetime NthWeekdayOfYearMonth(const int year, const int month, const int Nth, const ENUM_DAY_OF_WEEK weekday = SUNDAY) { if(Nth == 0 || month < 1 || month > 12) return 0; const datetime first = DateFrom(year, month, 1); const datetime last = DateFrom(year, month, DaysInMonth(year, month)); int jumpdays = (MathAbs(Nth) - 1) * 7; if(Nth > 0) { // Count from the beginning of the month. jumpdays += (7 + weekday - DayOfWeek(first)) % 7; datetime result = AddDays(first, jumpdays); return (result <= last) ? result : 0; } else { // Count from the end of the month. jumpdays += (7 - weekday + DayOfWeek(last)) % 7; datetime result = SubDays(last, jumpdays); return (result >= first) ? result : 0; } } //+------------------------------------------------------------------+ //| Return the first weekday of the month. | //+------------------------------------------------------------------+ datetime FirstWeekdayOfMonth(const datetime t, const ENUM_DAY_OF_WEEK weekday = SUNDAY) { return NthWeekdayOfYearMonth(Year(t), Month(t), 1, weekday); } //+------------------------------------------------------------------+ //| Return the last weekday of the month. | //+------------------------------------------------------------------+ datetime LastWeekdayOfMonth(const datetime t, const ENUM_DAY_OF_WEEK weekday = SUNDAY) { return NthWeekdayOfYearMonth(Year(t),Month(t),-1,weekday); } //+==================================================================+ //| WithXxx() / Replace() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the second updated. | //+------------------------------------------------------------------+ datetime WithSecond(const datetime t, const int second) { if(second < 0 || second > 59) return -1; return AddSeconds(t, second - Second(t)); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the minute updated. | //+------------------------------------------------------------------+ datetime WithMinute(const datetime t, const int minute) { if(minute < 0 || minute > 59) return -1; return AddMinutes(t, minute - Minute(t)); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the hour updated. | //+------------------------------------------------------------------+ datetime WithHour(const datetime t, const int hour) { if(hour < 0 || hour > 23) return -1; return AddHours(t, hour - Hour(t)); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the day of month updated.| //+------------------------------------------------------------------+ datetime WithDay(const datetime t, const int day) { if(day < 1 || day > DaysInMonth(Year(t), Month(t))) return -1; return AddDays(t, day - Day(t)); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the month updated. | //+------------------------------------------------------------------+ datetime WithMonth(const datetime t, const int month) { if(month < 1 || month > 12) return -1; return AddMonths(t, month - Month(t)); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the year updated. | //+------------------------------------------------------------------+ datetime WithYear(const datetime t, const int year) { if(year < 1970 || year > 3000) return -1; return AddYears(t, year - Year(t)); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime adjusted to the specified | //| weekday within the current week, preserving the time of day. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ datetime WithDayOfWeek(const datetime t, const ENUM_DAY_OF_WEEK weekday) { const int first = (int)TIMEUTILS_FIRST_DAY_OF_WEEK; const int current = DayOfWeek(t); int delta = (int)weekday - current; if((int)weekday < first) delta += 7; if(current < first) delta -= 7; return AddDays(t, delta); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the specified time, | //| preserving the date (i.e., replace time). | //+------------------------------------------------------------------+ datetime WithTime(const datetime t, const int hour, const int minute, const int second) { if(hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) return -1; datetime res = t; res = WithHour(res, hour); res = WithMinute(res, minute); return WithSecond(res, second); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the specified date, | //| preserving the time of day (i.e., replace date). | //+------------------------------------------------------------------+ datetime WithDate(const datetime t, const int year, const int month, const int day) { MqlDateTime dt; TimeToStructFast(t, dt); if(year < 1970 || year > 3000 || month < 1 || month > 12 || day < 1 || day > DaysInMonth(year, month)) return -1; dt.year = year; dt.mon = month; dt.day = day; return StructToTimeFast(dt); } //#################################################################### //# # //# Addition and Subtraction # //# # //#################################################################### //+==================================================================+ //| Add() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Add the specified number of seconds to the given date. | //+------------------------------------------------------------------+ datetime AddSeconds(const datetime t, const int amount) { return t + amount; } //+------------------------------------------------------------------+ //| Add the specified number of minutes to the given date. | //+------------------------------------------------------------------+ datetime AddMinutes(const datetime t, const int amount) { return t + ((datetime)amount * MINSECS); } //+------------------------------------------------------------------+ //| Add the specified number of hours to the given date. | //+------------------------------------------------------------------+ datetime AddHours(const datetime t, const int amount) { return t + ((datetime)amount * HOURSECS); } //+------------------------------------------------------------------+ //| Add the specified number of days to the given date. | //+------------------------------------------------------------------+ datetime AddDays(const datetime t, const int amount) { return t + ((datetime)amount * DAYSECS); } //+------------------------------------------------------------------+ //| Add the specified number of business days (Mon - Fri) to the | //| given date, ignoring weekends. | //+------------------------------------------------------------------+ datetime AddBusinessDays(const datetime t, const int amount) { int step = amount < 0 ? -1 : 1; int fullWeeks = amount / 5; int remaining = MathAbs(amount) % 5; datetime t_end = AddDays(t, fullWeeks * 7); // Loop over remaining business days while(remaining > 0) { t_end = AddDays(t_end, step); if(IsWeekday(t_end)) { remaining--; } } // If we add amount and land on a weekend, we add/reduce days // to land on the next business day. if(amount != 0) { if(IsSaturday(t_end)) t_end = AddDays(t_end, (step < 0 ? 2 : -1)); else if(IsSunday(t_end)) t_end = AddDays(t_end, (step < 0 ? 1 : -2)); } return t_end; } //+------------------------------------------------------------------+ //| Add the specified number of weeks to the given date. | //+------------------------------------------------------------------+ datetime AddWeeks(const datetime t, const int amount) { return t + ((datetime)amount * WEEKSECS); } //+------------------------------------------------------------------+ //| Add the specified number of months to the given date. | //+------------------------------------------------------------------+ datetime AddMonths(const datetime t, const int amount) { MqlDateTime dt; TimeToStructFast(t, dt); int totalMonths = dt.year * 12 + (dt.mon - 1) + amount; // month is 1-based dt.year = totalMonths / 12; dt.mon = (totalMonths % 12) + 1; dt.day = MathMin(dt.day, DaysInMonth(dt.year, dt.mon)); return StructToTimeFast(dt); } //+------------------------------------------------------------------+ //| Add the specified number of year quarters to the given date. | //+------------------------------------------------------------------+ datetime AddQuarters(const datetime t, const int amount) { return AddMonths(t, amount * 3); } //+------------------------------------------------------------------+ //| Add the specified number of years to the given date. | //+------------------------------------------------------------------+ datetime AddYears(const datetime t, const int amount) { return AddMonths(t, amount * 12); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the specified | //| calendar period added. The period is expressed in calendar | //| years, months, days, hours, minutes, and seconds. | //| | //| For periods returned by CalendarDifference(), | //| AddPeriod(from, period) reconstructs the original end date. | //+------------------------------------------------------------------+ datetime AddPeriod(const datetime t, const MqlDateTime& calendarPeriod) { if(calendarPeriod.year < 0) return -1; if(calendarPeriod.mon < 0 || calendarPeriod.mon > 11) return -1; if(calendarPeriod.day < 0) return -1; if(calendarPeriod.hour < 0 || calendarPeriod.hour > 23) return -1; if(calendarPeriod.min < 0 || calendarPeriod.min > 59) return -1; if(calendarPeriod.sec < 0 || calendarPeriod.sec > 59) return -1; datetime res = t; res = AddMonths(res, calendarPeriod.year * 12 + calendarPeriod.mon); res = AddDays(res, calendarPeriod.day); res = AddHours(res, calendarPeriod.hour); res = AddMinutes(res, calendarPeriod.min); res = AddSeconds(res, calendarPeriod.sec); return res; } //+==================================================================+ //| Sub() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Subtract the specified number of seconds from the given date. | //+------------------------------------------------------------------+ datetime SubSeconds(const datetime t, const int amount) { return AddSeconds(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of minutes from the given date. | //+------------------------------------------------------------------+ datetime SubMinutes(const datetime t, const int amount) { return AddMinutes(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of hours from the given date. | //+------------------------------------------------------------------+ datetime SubHours(const datetime t, const int amount) { return AddHours(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of days from the given date. | //+------------------------------------------------------------------+ datetime SubDays(const datetime t, const int amount) { return AddDays(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of business days (mon - fri) | //| from the given date, ignoring weekends. | //+------------------------------------------------------------------+ datetime SubBusinessDays(const datetime t, const int amount) { return AddBusinessDays(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of weeks from the given date. | //+------------------------------------------------------------------+ datetime SubWeeks(const datetime t, const int amount) { return AddWeeks(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of months from the given date. | //+------------------------------------------------------------------+ datetime SubMonths(const datetime t, const int amount) { return AddMonths(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of quarters from the given date. | //+------------------------------------------------------------------+ datetime SubQuarters(const datetime t, const int amount) { return AddQuarters(t, -amount); } //+------------------------------------------------------------------+ //| Subtract the specified number of years from the given date. | //+------------------------------------------------------------------+ datetime SubYears(const datetime t, const int amount) { return AddYears(t, -amount); } //+------------------------------------------------------------------+ //| Returns a copy of the given datetime with the specified | //| calendar period subtracted. The period is expressed in calendar | //| years, months, days, hours, minutes, and seconds. | //| | //| This function performs the inverse calendar operation of | //| AddPeriod(), applying the period in reverse order. | //| | //| Note that calendar arithmetic is generally not invertible due | //| to month-end clamping and varying month lengths. Therefore, for | //| periods returned by CalendarDifference(), | //| | //| AddPeriod(from, period) == to | //| | //| is guaranteed, but | //| | //| SubPeriod(to, period) == from | //| | //| is not guaranteed in all cases. | //+------------------------------------------------------------------+ datetime SubPeriod(const datetime t, const MqlDateTime& calendarPeriod) { if(calendarPeriod.year < 0) return -1; if(calendarPeriod.mon < 0 || calendarPeriod.mon > 11) return -1; if(calendarPeriod.day < 0) return -1; if(calendarPeriod.hour < 0 || calendarPeriod.hour > 23) return -1; if(calendarPeriod.min < 0 || calendarPeriod.min > 59) return -1; if(calendarPeriod.sec < 0 || calendarPeriod.sec > 59) return -1; datetime res = t; res = AddSeconds(res, -calendarPeriod.sec); res = AddMinutes(res, -calendarPeriod.min); res = AddHours(res, -calendarPeriod.hour); res = AddDays(res, -calendarPeriod.day); res = AddMonths(res, -(calendarPeriod.year * 12 + calendarPeriod.mon)); return res; } //#################################################################### //# # //# Difference # //# # //#################################################################### //+==================================================================+ //| DifferenceIn() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Returns the difference in the calendar day numbers between two | //| date/time values, ignoring the time-of-day components. | //+------------------------------------------------------------------+ int DifferenceInCalendarDays(const datetime from, const datetime to) { return DayIndex(to) - DayIndex(from); } //+------------------------------------------------------------------+ //| Returns the difference between the calendar week indices of | //| two date/time values, ignoring the time-of-day components. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int DifferenceInCalendarWeeks(const datetime from, const datetime to) { return WeekIndex(to) - WeekIndex(from); } //+------------------------------------------------------------------+ //| Returns the difference in the calendar month numbers between | //| two dates, ignoring the day and time components. | //+------------------------------------------------------------------+ int DifferenceInCalendarMonths(const datetime from, const datetime to) { return MonthIndex(to) - MonthIndex(from); } //+------------------------------------------------------------------+ //| Returns the difference in the calendar quarter numbers between | //| two dates, ignoring the month, day, and time components. | //+------------------------------------------------------------------+ int DifferenceInCalendarQuarters(const datetime from, const datetime to) { return QuarterIndex(to) - QuarterIndex(from); } //+------------------------------------------------------------------+ //| Returns the difference in the calendar year numbers between | //| two dates, ignoring the month, day, and time components. | //+------------------------------------------------------------------+ int DifferenceInCalendarYears(const datetime from, const datetime to) { return YearIndex(to) - YearIndex(from); } //+------------------------------------------------------------------+ //| Return the number of elapsed seconds between two dates. | //+------------------------------------------------------------------+ long DifferenceInSeconds(const datetime from, const datetime to) { return (long)(to - from); } //+------------------------------------------------------------------+ //| Return the number of elapsed minutes between two dates. | //+------------------------------------------------------------------+ int DifferenceInMinutes(const datetime from, const datetime to) { return (int)((to - from) / (int)MINSECS); } //+------------------------------------------------------------------+ //| Return the number of elapsed hours between two dates. | //+------------------------------------------------------------------+ int DifferenceInHours(const datetime from, const datetime to) { return (int)((to - from) / (int)HOURSECS); } //+------------------------------------------------------------------+ //| Return the number of elapsed 24-hour periods between two dates. | //+------------------------------------------------------------------+ int DifferenceInDays(const datetime from, const datetime to) { return (int)((to - from) / (int)DAYSECS); } //+------------------------------------------------------------------+ //| Return the number of elapsed full weeks between two dates. | //+------------------------------------------------------------------+ int DifferenceInWeeks(const datetime from, const datetime to) { return (int)((to - from) / (int)WEEKSECS); } //+------------------------------------------------------------------+ //| Return the number of elapsed full months between two dates. | //+------------------------------------------------------------------+ // DifferenceInCale DifferenceInMont | // | From | To | ndarMonths | hs | // |-------------|-------------|----------------: |----------------: | // | Jan 15 | Feb 14 | 1 | 0 | // | Jan 15 | Feb 15 | 1 | 1 | // | Jan 31 | Feb 28 | 1 | 1 | // | Jan 31 | Mar 30 | 2 | 1 | // | Jan 31 | Mar 31 | 2 | 2 | // | Feb 29 2024 | Feb 27 2025 | 12 | 11 | // | Feb 29 2024 | Feb 28 2025 | 12 | 12 | //+------------------------------------------------------------------+ int DifferenceInMonths(const datetime from, const datetime to) { if(from > to) return -DifferenceInMonths(to, from); int months = DifferenceInCalendarMonths(from, to); // https://github.com/dateutil/dateutil/blob/master/src/dateutil/relativedelta.py#L153 // add months back. If we've overshot our target, make an adjustment return AddMonths(from, months) <= to ? months : months - 1; } //+------------------------------------------------------------------+ //| Return the number of elapsed full quarters between dates. | //+------------------------------------------------------------------+ int DifferenceInQuarters(const datetime from, const datetime to) { return DifferenceInMonths(from, to) / 3; } //+------------------------------------------------------------------+ //| Return the number of elapsed full years between two dates. | //+------------------------------------------------------------------+ int DifferenceInYears(const datetime from, const datetime to) { return DifferenceInMonths(from, to) / 12; } //+------------------------------------------------------------------+ //| Return the number of business days (Mon-Fri) in the half-open | //| interval [from, to), excluding weekends. | //+------------------------------------------------------------------+ int DifferenceInBusinessDays(const datetime from, const datetime to) { int totalDays = DifferenceInCalendarDays(from, to); int step = totalDays < 0 ? -1 : 1; if(totalDays == 0) return 0; int fullWeeks = totalDays / 7; int business = fullWeeks * 5; int remaining = MathAbs(totalDays) % 7; datetime dt_temp = from; // Loop over remaining days not part of a full week for(int i = 0; i < remaining; i++) { if(IsWeekday(dt_temp)) { business += step; } dt_temp = AddDays(dt_temp, step); } return business; } //+------------------------------------------------------------------+ //| Return the number of weekend days in the half-open interval | //| [from, to). The end date is not included. | //+------------------------------------------------------------------+ int DifferenceInWeekendDays(const datetime from, const datetime to) { return DifferenceInCalendarDays(from, to) - DifferenceInBusinessDays(from, to); } //+------------------------------------------------------------------+ //| Returns the calendar difference between two dates, broken down | //| into years, months, days, hours, minutes, and seconds. | //+------------------------------------------------------------------+ bool CalendarDifference(datetime from, datetime to, MqlDateTime& diff) { const static MqlDateTime zero = {}; diff = zero; if(from == to) return(true); if(from > to) { datetime temp = from; from = to; to = temp; } const int totalMonths = DifferenceInMonths(from, to); diff.year = totalMonths / 12; diff.mon = totalMonths % 12; from = AddMonths(from, totalMonths); diff.day = DifferenceInDays(from, to); from = AddDays(from, diff.day); diff.hour = DifferenceInHours(from, to); from = AddHours(from, diff.hour); diff.min = DifferenceInMinutes(from, to); from = AddMinutes(from, diff.min); diff.sec = (int)DifferenceInSeconds(from, to); return (true); } //+------------------------------------------------------------------+ //| Returns the calendar difference between two dates as a | //| human-readable string (e.g. "2y 3m 5d 04:12:30"). | //+------------------------------------------------------------------+ string CalendarDifferenceToString(const datetime from, const datetime to) { if(from == to) return "0y 0m 0d 00:00:00"; MqlDateTime diff; CalendarDifference(from, to, diff); string result = ""; result += IntegerToString(diff.year); result += "y " + IntegerToString(diff.mon); result += "m " + IntegerToString(diff.day); result += "d " + IntegerToString(diff.hour, 2, '0'); result += ":" + IntegerToString(diff.min, 2, '0'); result += ":" + IntegerToString(diff.sec, 2, '0'); return result; } //#################################################################### //# # //# Comparison and Checks # //# # //#################################################################### //+==================================================================+ //| Is() Checks | //+==================================================================+ //+------------------------------------------------------------------+ //| Is the given date the first day of a month? | //+------------------------------------------------------------------+ bool IsFirstDayOfMonth(const datetime t) { return Day(t) == 1; } //+------------------------------------------------------------------+ //| Is the given date the last day of a month? | //+------------------------------------------------------------------+ bool IsLastDayOfMonth(const datetime t) { return EndOfDay(t) == EndOfMonth(t); } //+------------------------------------------------------------------+ //| Does the given date fall on a weekend? | //+------------------------------------------------------------------+ bool IsWeekend(const datetime t) { int dow = DayOfWeek(t); return dow == SATURDAY || dow == SUNDAY; } //+------------------------------------------------------------------+ //| Does the given date fall on a business day? | //+------------------------------------------------------------------+ bool IsWeekday(const datetime t) { return !IsWeekend(t); } //+------------------------------------------------------------------+ //| Is the given date Sunday? | //+------------------------------------------------------------------+ bool IsSunday(const datetime t) { return DayOfWeek(t) == SUNDAY; } //+------------------------------------------------------------------+ //| Is the given date Monday? | //+------------------------------------------------------------------+ bool IsMonday(const datetime t) { return DayOfWeek(t) == MONDAY; } //+------------------------------------------------------------------+ //| Is the given date Tuesday? | //+------------------------------------------------------------------+ bool IsTuesday(const datetime t) { return DayOfWeek(t) == TUESDAY; } //+------------------------------------------------------------------+ //| Is the given date Wednesday? | //+------------------------------------------------------------------+ bool IsWednesday(const datetime t) { return DayOfWeek(t) == WEDNESDAY; } //+------------------------------------------------------------------+ //| Is the given date Thursday? | //+------------------------------------------------------------------+ bool IsThursday(const datetime t) { return DayOfWeek(t) == THURSDAY; } //+------------------------------------------------------------------+ //| Is the given date Friday? | //+------------------------------------------------------------------+ bool IsFriday(const datetime t) { return DayOfWeek(t) == FRIDAY; } //+------------------------------------------------------------------+ //| Is the given date Saturday? | //+------------------------------------------------------------------+ bool IsSaturday(const datetime t) { return DayOfWeek(t) == SATURDAY; } //+==================================================================+ //| IsSame() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same minute. | //+------------------------------------------------------------------+ bool IsSameMinute(const datetime a, const datetime b) { return MinuteIndex(a) == MinuteIndex(b); } //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same hour. | //+------------------------------------------------------------------+ bool IsSameHour(const datetime a, const datetime b) { return HourIndex(a) == HourIndex(b); } //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same day. | //+------------------------------------------------------------------+ bool IsSameDay(const datetime a, const datetime b) { return DayIndex(a) == DayIndex(b); } //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same week. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ bool IsSameWeek(const datetime a, const datetime b) { return WeekIndex(a) == WeekIndex(b); } //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same month. | //+------------------------------------------------------------------+ bool IsSameMonth(const datetime a, const datetime b) { return MonthIndex(a) == MonthIndex(b); } //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same quarter | //+------------------------------------------------------------------+ bool IsSameQuarter(const datetime a, const datetime b) { return QuarterIndex(a) == QuarterIndex(b); } //+------------------------------------------------------------------+ //| Check whether both date/time values fall within the same year. | //+------------------------------------------------------------------+ bool IsSameYear(const datetime a, const datetime b) { return YearIndex(a) == YearIndex(b); } //+==================================================================+ //| IsCurrent() Units | //+==================================================================+ //+------------------------------------------------------------------+ //| Is the given date in the same minute as the current server time | //+------------------------------------------------------------------+ bool IsCurrentMinute(const datetime t) { return IsSameMinute(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is the given date in the same hour as the current server time | //+------------------------------------------------------------------+ bool IsCurrentHour(const datetime t) { return IsSameHour(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is the given date in the same week as the current server time | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ bool IsCurrentWeek(const datetime t) { return IsSameWeek(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is the given date in the same month as the current server time | //+------------------------------------------------------------------+ bool IsCurrentMonth(const datetime t) { return IsSameMonth(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is this date in the same quarter (and year) as the server ? | //+------------------------------------------------------------------+ bool IsCurrentQuarter(const datetime t) { return IsSameQuarter(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is the given date in the same year as the current server time | //+------------------------------------------------------------------+ bool IsCurrentYear(const datetime t) { return IsSameYear(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is the given date today on the trade server | //+------------------------------------------------------------------+ bool IsToday(const datetime t) { return IsSameDay(t, TimeTradeServer()); } //+------------------------------------------------------------------+ //| Is the given date tomorrow on the trade server | //+------------------------------------------------------------------+ bool IsTomorrow(const datetime t) { return IsSameDay(t, AddDays(TimeTradeServer(), 1)); } //+------------------------------------------------------------------+ //| Is the given date yesterday on the trade server | //+------------------------------------------------------------------+ bool IsYesterday(const datetime t) { return IsSameDay(t, SubDays(TimeTradeServer(), 1)); } //+==================================================================+ //| Session() Checks | //+==================================================================+ //+------------------------------------------------------------------+ //| Returns true if the specified datetime falls within the | //| specified recurring daily session [start, end). | //| | //| The session repeats every day at the same start and end times. | //| | //| If start <= end, the session occurs within a single day. | //| If start > end, the session spans midnight into the next day. | //+------------------------------------------------------------------+ bool IsInSession(const datetime t, const int startHour, const int startMinute, const int endHour, const int endMinute) { if(startHour < 0 || startHour > 23 || startMinute < 0 || startMinute > 59 || endHour < 0 || endHour > 23 || endMinute < 0 || endMinute > 59) return false; const int current = SecondsSinceMidnight(t); const int start = startHour * HOURSECS + startMinute * MINSECS; const int end = endHour * HOURSECS + endMinute * MINSECS; return (start <= end) ? (current >= start && current < end) : (current >= start || current < end); } //+------------------------------------------------------------------+ //| Returns true if the current server time falls within the | //| specified recurring daily session [start, end). | //+------------------------------------------------------------------+ bool IsInSession(const int startHour, const int startMinute, const int endHour, const int endMinute) { return IsInSession( TimeTradeServer(), startHour, startMinute, endHour, endMinute); } //+------------------------------------------------------------------+ //| Returns true if the current server time falls within the | //| specified recurring daily session [start, end). | //| | //| Time strings must be in "HH:MM" or "HH:MM:SS" format. | //+------------------------------------------------------------------+ bool IsInSession(const string startTime, const string endTime) { const datetime start = DateFromString(startTime); const datetime end = DateFromString(endTime); return IsInSession( TimeTradeServer(), Hour(start), Minute(start), Hour(end), Minute(end)); } //+------------------------------------------------------------------+ //| Returns true if two half-open intervals [aStart, aEnd) and | //| [bStart, bEnd) overlap. | //| | //| If an overlap exists, the overlapping interval is written to | //| overlapStart and overlapEnd. | //| | //| If the intervals do not overlap, or either interval is invalid | //| (end < start), returns false and sets both output values to 0. | //+------------------------------------------------------------------+ bool SessionOverlap(const datetime aStart, const datetime aEnd, const datetime bStart, const datetime bEnd, datetime &overlapStart, datetime &overlapEnd) { overlapStart = 0; overlapEnd = 0; if(aEnd < aStart || bEnd < bStart) return false; const datetime s = MathMax(aStart, bStart); const datetime e = MathMin(aEnd, bEnd); if(s >= e) return false; overlapStart = s; overlapEnd = e; return true; } //+==================================================================+ //| Misc | //+==================================================================+ //+------------------------------------------------------------------+ //| Checks whether the given year is a leap year or not | //+------------------------------------------------------------------+ bool IsLeapYear(const int year) { //return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); // From: https://www.youtube.com/watch?v=0s9F4QWAl-E&t=1790s return (year & ((year % 100 != 0) ? 3 : 15)) == 0; } //+------------------------------------------------------------------+ //| Returns the number of days in a month of the given year. | //+------------------------------------------------------------------+ int DaysInMonth(const int year, const int month) { //const int dim[13] = {0, 31, (IsLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //return dim[month % 13]; // From: https://www.youtube.com/watch?v=0s9F4QWAl-E&t=1790s if(month == 2) return 28 + IsLeapYear(year); return 30 | (month ^ (month >> 3)); } //+------------------------------------------------------------------+ //| Returns the number of days in a given year. | //+------------------------------------------------------------------+ int DaysInYear(const int year) { return 365 + IsLeapYear(year); } //+==================================================================+ //| Week Utilities | //+==================================================================+ //+------------------------------------------------------------------+ //| Returns the calendar week number of the month (1...6). | //| | //| Week 1 is the first calendar week containing the first day of | //| the month. The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int WeekOfMonth(const datetime t) { return WeekIndex(t) - WeekIndex(StartOfMonth(t)) + 1; } //+------------------------------------------------------------------+ //| Returns the calendar week number of the year (1...54). | //| | //| Week 1 is the first calendar week containing January 1st. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int WeekOfYear(const datetime t) { return WeekIndex(t) - WeekIndex(StartOfYear(t)) + 1; } //+------------------------------------------------------------------+ //| Returns the number of calendar weeks spanned by the specified | //| month. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int WeeksInMonth(const int year, const int month) { const datetime first = DateFrom(year, month, 1); return WeekIndex(EndOfMonth(first)) - WeekIndex(first) + 1; } //+------------------------------------------------------------------+ //| Returns the number of calendar weeks spanned by the specified | //| year. | //| The result depends on TIMEUTILS_FIRST_DAY_OF_WEEK. | //+------------------------------------------------------------------+ int WeeksInYear(const int year) { const datetime first = DateFrom(year, 1, 1); return WeekIndex(EndOfYear(first)) - WeekIndex(first) + 1; } //#################################################################### //# # //# Format & Display # //# # //#################################################################### //+==================================================================+ //| Formating Time to String | //+==================================================================+ //+------------------------------------------------------------------+ //| Format time with the weekday name => "Wed, 2023.02.14 01:59" | //+------------------------------------------------------------------+ string t2s(const datetime t, const int mode = TIME_DATE | TIME_MINUTES) { const static string days[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; return days[ DayOfWeek(t) ] + ", " + TimeToString(t, mode); } //+------------------------------------------------------------------+ //| Format the time in seconds to a string (like 2d 14:58:04) | //+------------------------------------------------------------------+ string SecondsToString(const int seconds) { const int days = (int)(seconds / DAYSECS); const string d = days ? (string)days + "d " : ""; return d + TimeToString(seconds, TIME_SECONDS); } //+------------------------------------------------------------------+ //| Return the month name for a month number [1-12] | //+------------------------------------------------------------------+ string MonthName(const int monthNo) { const static string months[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; return (monthNo < 1 || monthNo > 12) ? "Undefined monthNo " + (string)monthNo : months[monthNo - 1]; } //+------------------------------------------------------------------+ //| Return the weekday name for a weekday number [0-6] | //+------------------------------------------------------------------+ string DayName(const int dayNo) { const static string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; return (dayNo < 0 || dayNo > 6) ? "Undefined dayNo " + (string)dayNo : days[dayNo]; } //+------------------------------------------------------------------+ //| Get the formatted time according to the passed string of tokens. | //| List of all available formats: | //| Format Output Description | //| ------ ---------------- ------------------------------------- | //| YY 18 Two-digit year | //| YYYY 2018 Four-digit year | //| M 1-12 The month, beginning at 1 | //| MM 01-12 The month, 2-digits | //| MMM Jan-Dec The abbreviated month name, 3-letters | //| MMMM January-December The full month name | //| D 1-31 The day of the month | //| DD 01-31 The day of the month, 2-digits | //| DDD Sun-Sat The short name of the day of the week | //| DDDD Sunday-Saturday The name of the day of the week | //| h 0-23 The hour | //| hh 00-23 The hour, 2-digits | //| H 1-12 The hour, 12-hour clock | //| HH 01-12 The hour, 12-hour clock, 2-digits | //| m 0-59 The minute | //| mm 00-59 The minute, 2-digits | //| s 0-59 The second | //| ss 00-59 The second, 2-digits | //| A AM PM | //| a am pm | //+------------------------------------------------------------------+ //| Sample formats: | //| "YYYY.MM.DD hh:mm" // "2024.12.08 22:05" (default) | //| "DDD, YYYY.MM.DD hh:mm:ss" // "Sun, 2024.12.08 22:05:21" | //| "D MMMM YYYY, HH:mm a" // "8 December 2024, 10:05 pm" | //| "DD/MM/YYYY" // "08/12/2024" | //+------------------------------------------------------------------+ string TimeFormat(const datetime t, const string format = "YYYY.MM.DD hh:mm") { string retVal; MqlDateTime dt_struct; if(format == "" || StringLen(format) == 0) { Print("invalid format"); return ""; } if(TimeToStructFast(t, dt_struct) == false) { Print("TimeToStructFast() failed. Error ", GetLastError()); return ""; } string token = ""; int index_char = 0; while (index_char < StringLen(format)) { // get next token from format string do { token += StringSubstr(format, index_char, 1); index_char++; } while (index_char < StringLen(format) && format[index_char] == token[StringLen(token) - 1]); // format datetime value based on format token if(token == "YYYY") { retVal += IntegerToString(dt_struct.year); } else if(token == "YY") { retVal += IntegerToString(dt_struct.year % 100, 2, '0'); } else if(token == "MMMM") { retVal += MonthName(dt_struct.mon); } else if(token == "MMM") { retVal += StringSubstr(MonthName(dt_struct.mon), 0, 3); } else if(token == "MM") { retVal += IntegerToString(dt_struct.mon, 2, '0'); } else if(token == "M") { retVal += IntegerToString(dt_struct.mon); } else if(token == "DDDD") { retVal += DayName(dt_struct.day_of_week); } else if(token == "DDD") { retVal += StringSubstr(DayName(dt_struct.day_of_week), 0, 3); } else if(token == "DD") { retVal += IntegerToString(dt_struct.day, 2, '0'); } else if(token == "D") { retVal += IntegerToString(dt_struct.day); } else if(token == "hh") { retVal += IntegerToString(dt_struct.hour, 2, '0'); } else if(token == "h") { retVal += IntegerToString(dt_struct.hour); } else if(token == "HH") { retVal += IntegerToString((bool)(dt_struct.hour % 12) ? dt_struct.hour % 12 : 12, 2, '0'); } else if(token == "H") { retVal += IntegerToString((bool)(dt_struct.hour % 12) ? dt_struct.hour % 12 : 12); } else if(token == "mm") { retVal += IntegerToString(dt_struct.min, 2, '0'); } else if(token == "m") { retVal += IntegerToString(dt_struct.min); } else if(token == "ss") { retVal += IntegerToString(dt_struct.sec, 2, '0'); } else if(token == "s") { retVal += IntegerToString(dt_struct.sec); } else if(token == "A") { retVal += dt_struct.hour < 12 ? "AM" : "PM"; } else if(token == "a") { retVal += dt_struct.hour < 12 ? "am" : "pm"; } else { // if there are any non-matching characters left in format string retVal += token; } token = ""; } return (retVal); } #undef DAYS_PER_4_YEARS #undef DAYS_PER_400_YEARS #undef DAYS_TO_1970 #undef MARCH1_BASED_DOY #endif // #ifndef TIMEUTILS_UNIQUE_HEADER_ID_H //+------------------------------------------------------------------+ /* example code: #include "TimeUtils.mqh" void OnStart() { datetime t = TimeLocal(); Print( t2s(t, TIME_DATE|TIME_SECONDS) ); // Formats time with the weekday name Print( Year(t) ); Print( Month(t) ); Print( Day(t) ); Print( Hour(t) ); Print( Minute(t) ); Print( Second(t) ); Print( DayOfWeek(t) ); Print( DayOfYear(t) ); MqlDateTime dt[1] = {}; TimeToStructFast(t, dt[0]); ArrayPrint(dt); dt[0].year += 1; Print(StructToTimeFast(dt[0])); } example output: Tue, 2024.12.03 20:46:58 2024 12 3 20 46 58 2 337 [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year] [0] 2024 12 3 20 46 58 2 337 2025.12.03 20:46:58 */ //+------------------------------------------------------------------+