Although, I suspect its irrelevant due to the times being actually calculated, here is a code that does the correct "IsLeapYear" calculations a bit more refined:
// Months #define JANUARY mqlplus_month_JANUARY #define FEBRUARY mqlplus_month_FEBRUARY #define MARCH mqlplus_month_MARCH #define APRIL mqlplus_month_APRIL #define MAY mqlplus_month_MAY #define JUNE mqlplus_month_JUNE #define JULY mqlplus_month_JULY #define AUGUST mqlplus_month_AUGUST #define SEPTEMBER mqlplus_month_SEPTEMBER #define OCTOBER mqlplus_month_OCTOBER #define NOVEMBER mqlplus_month_NOVEMBER #define DECEMBER mqlplus_month_DECEMBER #define ENUM_MONTH_OF_YEAR mqlplus_enum_month_of_year enum ENUM_MONTH_OF_YEAR { mqlplus_month_JANUARY = 0x01, // January mqlplus_month_FEBRUARY = 0x02, // February mqlplus_month_MARCH = 0x03, // March mqlplus_month_APRIL = 0x04, // April mqlplus_month_MAY = 0x05, // May mqlplus_month_JUNE = 0x06, // June mqlplus_month_JULY = 0x07, // July mqlplus_month_AUGUST = 0x08, // August mqlplus_month_SEPTEMBER = 0x09, // September mqlplus_month_OCTOBER = 0x0A, // October mqlplus_month_NOVEMBER = 0x0B, // November mqlplus_month_DECEMBER = 0x0C // December }; const int mqlplus_DaysInMonth(const ENUM_MONTH_OF_YEAR month, const int year) { switch(month) { case JANUARY: return(31); case FEBRUARY: return(28 + (((year % 4) == NULL) && ((year % 100) != NULL)) + (((year % 100) == NULL) && ((year % 400) != NULL)) + ((year % 400) == NULL)); case MARCH: return(31); case APRIL: return(30); case MAY: return(31); case JUNE: return(30); case JULY: return(31); case AUGUST: return(31); case SEPTEMBER: return(30); case OCTOBER: return(31); case NOVEMBER: return(30); case DECEMBER: return(31); default: return(NULL); } }
Although, I suspect its irrelevant due to the times being actually calculated, here is a code that does the correct "IsLeapYear" calculations a bit more refined:
Thanks for you idea, However I am seeing this is more elegant:
bool IsLeapYear(const int year) { // From: https://www.youtube.com/watch?v=0s9F4QWAl-E&t=1790s int d = (year % 100 != 0) ? 4 : 16; return (year & (d - 1)) == 0; } 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]; }
and faster, as the check for leap year requires 1 branching (comparison).
Also, the check for February is embbeded into the lookup array.
or, as one-liner :
bool IsLeapYear(const int year) { return (year & ((year % 100 != 0) ? 3 : 15)) == 0; }
Thanks for you idea, However I am seeing this is more elegant:
and faster, as the check for leap year requires 1 branching (comparison).
Also, the check for February is embbeded into the lookup array.
or, as one-liner :
benchmark:
bool IsLeapYear(const int year) { return (year & ((year % 100 != 0) ? 3 : 15)) == 0; } //+------------------------------------------------------------------+ int DaysInMonth_v1(const int year, const int month) { switch(month) { case 2: return 28 + IsLeapYear(year); case 4: case 6: case 9: case 11: return 30; default: return 31; } } //+------------------------------------------------------------------+ int DaysInMonth_v2(const int year, const int month) { const int dim[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; return (month == 2 && IsLeapYear(year)) ? 29 : dim[month % 13]; } //+------------------------------------------------------------------+ int DaysInMonth_v3(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]; } // Compiler Version: 4620, X64 Regular // 13th Gen Intel Core i7-13700KF, AVX2 + FMA3 // 3.58 ns, checksum = 108596907345 // DaysInMonth_v1 // 1.48 ns, checksum = 108596907345 // DaysInMonth_v2 // 1.24 ns, checksum = 108596907345 // DaysInMonth_v3the switch statement has more branches.
Forum on trading, automated trading systems and testing trading strategies
Libraries: High-Performance Time Functions (TimeUtils)
amrali, 2024.12.04 22:49
int DaysInMonth_v2(const int year, const int month) { static const int dim[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; return (month == 2 && IsLeapYear(year)) ? 29 : dim[month % 13]; }
int DaysInMonth_v4(const int year, const int month) { if (month == 2) return(28 + IsLeapYear(year)); return(30 | (month ^ (month >> 3))); }

Thanks!
Compiler Version: 4620, X64 Regular 13th Gen Intel Core i7-13700KF, AVX2 + FMA3 3.54 ns, checksum = 108596882915 // DaysInMonth_v1 1.51 ns, checksum = 108596882915 // DaysInMonth_v2 1.26 ns, checksum = 108596882915 // DaysInMonth_v3 1.08 ns, checksum = 108596882915 // DaysInMonth_v4
Update 5 December 2024 - version 1.15
1. optimized calculations in DaysInMonth() function.
2. added new functions:
//+==================================================================+ //| Nth() Weekday Of The Month | //+==================================================================+ datetime FirstWeekdayOfTheMonth(datetime t, ENUM_DAY_OF_WEEK weekday = SUNDAY) datetime LastWeekdayOfTheMonth(datetime t, ENUM_DAY_OF_WEEK weekday = SUNDAY) datetime NthWeekdayOfTheMonth(datetime t, int Nth, ENUM_DAY_OF_WEEK weekday = SUNDAY) //+==================================================================+ //| Add() Units | //+==================================================================+ datetime AddBusinessDays(datetime t, int amount) //+==================================================================+ //| Sub() Units | //+==================================================================+ datetime SubBusinessDays(datetime t, int amount) //+==================================================================+ //| DifferenceIn() Units | //+==================================================================+ int DifferenceInBusinessDays(datetime beginTime, datetime endTime) //+==================================================================+ //| Misc | //+==================================================================+ datetime GetNthWeekdayInYearMonth(iYear, iMonth, Nth, weekday = SUNDAY) datetime GetNthSundayInYearMonth(iYear, iMonth, Nth) //+==================================================================+ //| Formating Time to String | //+==================================================================+ string SecondsToString(int seconds)
datetime CreateDateTime( 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 StructToTime(dt); // static const uint Months[] = {0, 11512676, 11512180, 11511728, 11511232, 11510750, 11510256, // 11509774, 11509280, 11508781, 11508302, 11507806, 11507326 // }; static const uint Months[] = {0, 11512692, 11512196, 11511744, 11511248, 11510766, 11510272, 11509790, 11509296, 11508797, 11508318, 11507822, 11507342 }; // return (((year * 5844 - Months[mon]) >> 4) + day - 1) * DAYSECS + (hour * HOURSECS + min * MINSECS + sec); return (((year * 5844 - Months[mon]) >> 4) + day) * DAYSECS + (hour * HOURSECS + min * MINSECS + sec); }

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
High-Performance Time Functions (TimeUtils):
High-performmance functions for dealing with time.
Author: amrali