581 lines
17 KiB
MQL5
581 lines
17 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| DateTime.mqh |
|
|
//| Copyright 2000-2025, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| Structure CDateTime. |
|
|
//| Purpose: Working with dates and time. |
|
|
//| Extends the MqlDateTime structure. |
|
|
//+------------------------------------------------------------------+
|
|
struct CDateTime : public MqlDateTime
|
|
{
|
|
//--- additional information
|
|
string MonthName(const int num) const;
|
|
string ShortMonthName(const int num) const;
|
|
string DayName(const int num) const;
|
|
string ShortDayName(const int num) const;
|
|
string MonthName(void) const { return(MonthName(mon)); }
|
|
string ShortMonthName(void) const { return(ShortMonthName(mon)); }
|
|
string DayName(void) const { return(DayName(day_of_week)); }
|
|
string ShortDayName(void) const { return(ShortDayName(day_of_week)); }
|
|
int DaysInMonth(void) const;
|
|
//--- data access
|
|
datetime DateTime(void) { return(StructToTime(this)); }
|
|
void DateTime(const datetime value) { TimeToStruct(value,this); }
|
|
void DateTime(const MqlDateTime& value) { this=value; }
|
|
void Date(const datetime value);
|
|
void Date(const MqlDateTime &value);
|
|
void Time(const datetime value);
|
|
void Time(const MqlDateTime &value);
|
|
//--- settings
|
|
void Sec(const int value);
|
|
void Min(const int value);
|
|
void Hour(const int value);
|
|
void Day(const int value);
|
|
void Mon(const int value);
|
|
void Year(const int value);
|
|
//--- increments
|
|
void SecDec(int delta=1);
|
|
void SecInc(int delta=1);
|
|
void MinDec(int delta=1);
|
|
void MinInc(int delta=1);
|
|
void HourDec(int delta=1);
|
|
void HourInc(int delta=1);
|
|
void DayDec(int delta=1);
|
|
void DayInc(int delta=1);
|
|
void MonDec(int delta=1);
|
|
void MonInc(int delta=1);
|
|
void YearDec(int delta=1);
|
|
void YearInc(int delta=1);
|
|
//--- check
|
|
void DayCheck(void);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Gets month name |
|
|
//+------------------------------------------------------------------+
|
|
string CDateTime::MonthName(const int num) const
|
|
{
|
|
switch(num)
|
|
{
|
|
case 1: return("January");
|
|
case 2: return("February");
|
|
case 3: return("March");
|
|
case 4: return("April");
|
|
case 5: return("May");
|
|
case 6: return("June");
|
|
case 7: return("July");
|
|
case 8: return("August");
|
|
case 9: return("September");
|
|
case 10: return("October");
|
|
case 11: return("November");
|
|
case 12: return("December");
|
|
}
|
|
//---
|
|
return("Bad month");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Gets short name of month |
|
|
//+------------------------------------------------------------------+
|
|
string CDateTime::ShortMonthName(const int num) const
|
|
{
|
|
switch(num)
|
|
{
|
|
case 1: return("jan");
|
|
case 2: return("feb");
|
|
case 3: return("mar");
|
|
case 4: return("apr");
|
|
case 5: return("may");
|
|
case 6: return("jun");
|
|
case 7: return("jul");
|
|
case 8: return("aug");
|
|
case 9: return("sep");
|
|
case 10: return("oct");
|
|
case 11: return("nov");
|
|
case 12: return("dec");
|
|
}
|
|
//---
|
|
return("Bad month");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Gets name of week day |
|
|
//+------------------------------------------------------------------+
|
|
string CDateTime::DayName(const int num) const
|
|
{
|
|
switch(num)
|
|
{
|
|
case 0: return("Sunday");
|
|
case 1: return("Monday");
|
|
case 2: return("Tuesday");
|
|
case 3: return("Wednesday");
|
|
case 4: return("Thursday");
|
|
case 5: return("Friday");
|
|
case 6: return("Saturday");
|
|
}
|
|
//---
|
|
return("Bad day of week");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Gets short name of week day |
|
|
//+------------------------------------------------------------------+
|
|
string CDateTime::ShortDayName(const int num) const
|
|
{
|
|
switch(num)
|
|
{
|
|
case 0: return("Su");
|
|
case 1: return("Mo");
|
|
case 2: return("Tu");
|
|
case 3: return("We");
|
|
case 4: return("Th");
|
|
case 5: return("Fr");
|
|
case 6: return("Sa");
|
|
}
|
|
//---
|
|
return("Bad day of week");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Gets number of days in month |
|
|
//+------------------------------------------------------------------+
|
|
int CDateTime::DaysInMonth(void) const
|
|
{
|
|
int leap_year;
|
|
//---
|
|
switch(mon)
|
|
{
|
|
case 1:
|
|
case 3:
|
|
case 5:
|
|
case 7:
|
|
case 8:
|
|
case 10:
|
|
case 12:
|
|
return(31);
|
|
case 2:
|
|
leap_year=year;
|
|
if(year%100==0)
|
|
leap_year/=100;
|
|
return((leap_year%4==0)? 29 : 28);
|
|
case 4:
|
|
case 6:
|
|
case 9:
|
|
case 11:
|
|
return(30);
|
|
}
|
|
//---
|
|
return(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets date |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Date(const datetime value)
|
|
{
|
|
MqlDateTime dt;
|
|
//--- convert to structure
|
|
TimeToStruct(value,dt);
|
|
//--- set
|
|
Date(dt);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets date |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Date(const MqlDateTime &value)
|
|
{
|
|
day =value.day;
|
|
mon =value.mon;
|
|
year=value.year;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets time |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Time(const datetime value)
|
|
{
|
|
MqlDateTime dt;
|
|
//--- convert to structure
|
|
TimeToStruct(value,dt);
|
|
//--- set
|
|
Time(dt);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets time |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Time(const MqlDateTime &value)
|
|
{
|
|
hour=value.hour;
|
|
min =value.min;
|
|
sec =value.sec;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets seconds |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Sec(const int value)
|
|
{
|
|
//--- check and set
|
|
if(value>=0 && value<60)
|
|
sec=value;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets minutes |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Min(const int value)
|
|
{
|
|
//--- check and set
|
|
if(value>=0 && value<60)
|
|
min=value;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets hours |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Hour(const int value)
|
|
{
|
|
//--- check and set
|
|
if(value>=0 && value<24)
|
|
hour=value;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets day of month |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Day(const int value)
|
|
{
|
|
//--- check and set
|
|
if(value>0 && value<=DaysInMonth())
|
|
{
|
|
day=value;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets month |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Mon(const int value)
|
|
{
|
|
//--- check and set
|
|
if(value>0 && value<=12)
|
|
{
|
|
mon=value;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Sets year |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::Year(const int value)
|
|
{
|
|
//--- check and set
|
|
if(value>=1970)
|
|
{
|
|
year=value;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Subtracts specified number of seconds |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::SecDec(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
SecInc(-delta);
|
|
return;
|
|
}
|
|
//--- check if subtract from upper number positions
|
|
if(delta>60)
|
|
{
|
|
MinDec(delta/60);
|
|
delta%=60;
|
|
}
|
|
sec-=delta;
|
|
if(sec<0)
|
|
{
|
|
sec+=60;
|
|
MinDec();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Adds specified number of seconds |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::SecInc(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
SecDec(-delta);
|
|
return;
|
|
}
|
|
//--- check if add to upper number positions
|
|
if(delta>60)
|
|
{
|
|
MinInc(delta/60);
|
|
delta%=60;
|
|
}
|
|
sec+=delta;
|
|
if(sec>=60)
|
|
{
|
|
sec-=60;
|
|
MinInc();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Subtracts specified number of minutes |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::MinDec(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
MinInc(-delta);
|
|
return;
|
|
}
|
|
//--- check if subtract from upper number positions
|
|
if(delta>60)
|
|
{
|
|
HourDec(delta/60);
|
|
delta%=60;
|
|
}
|
|
min-=delta;
|
|
if(min<0)
|
|
{
|
|
min+=60;
|
|
HourDec();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Adds specified number of minutes |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::MinInc(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
MinDec(-delta);
|
|
return;
|
|
}
|
|
//--- check if add to upper number positions
|
|
if(delta>60)
|
|
{
|
|
HourInc(delta/60);
|
|
delta%=60;
|
|
}
|
|
min+=delta;
|
|
if(min>=60)
|
|
{
|
|
min-=60;
|
|
HourInc();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Subtracts specified number of hours |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::HourDec(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
HourInc(-delta);
|
|
return;
|
|
}
|
|
//--- check if subtract from upper number positions
|
|
if(delta>24)
|
|
{
|
|
DayDec(delta/24);
|
|
delta%=24;
|
|
}
|
|
hour-=delta;
|
|
if(hour<0)
|
|
{
|
|
hour+=24;
|
|
DayDec();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Adds specified number of hours |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::HourInc(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
HourDec(-delta);
|
|
return;
|
|
}
|
|
//--- check if add to upper number positions
|
|
if(delta>24)
|
|
{
|
|
DayInc(delta/24);
|
|
delta%=24;
|
|
}
|
|
hour+=delta;
|
|
if(hour>=24)
|
|
{
|
|
hour-=24;
|
|
DayInc();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Subtracts specified number of days |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::DayDec(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
DayInc(-delta);
|
|
return;
|
|
}
|
|
//--- uncertain condition, as the number of days in month can differ
|
|
while(day<=delta)
|
|
{
|
|
delta-=day;
|
|
MonDec();
|
|
day=DaysInMonth();
|
|
}
|
|
day-=delta;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Adds specified number of days |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::DayInc(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
DayDec(-delta);
|
|
return;
|
|
}
|
|
//--- uncertain condition, as the number of days in month can differ
|
|
while(DaysInMonth()-day<delta)
|
|
{
|
|
delta-=DaysInMonth()-day+1;
|
|
MonInc();
|
|
day=1;
|
|
}
|
|
day+=delta;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Subtracts specified number of months |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::MonDec(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
MonInc(-delta);
|
|
return;
|
|
}
|
|
//--- check if subtract from upper number positions
|
|
if(delta>12)
|
|
{
|
|
YearDec(delta/12);
|
|
delta%=12;
|
|
}
|
|
mon-=delta;
|
|
if(mon<=0)
|
|
{
|
|
mon+=12;
|
|
YearDec();
|
|
}
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Adds specified number of months |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::MonInc(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta==0)
|
|
return;
|
|
//--- if increment is negative - inverse the operation
|
|
if(delta<0)
|
|
{
|
|
MonDec(-delta);
|
|
return;
|
|
}
|
|
//--- check if add to upper number positions
|
|
if(delta>12)
|
|
{
|
|
YearInc(delta/12);
|
|
delta%=12;
|
|
}
|
|
mon+=delta;
|
|
if(mon>12)
|
|
{
|
|
mon-=12;
|
|
YearInc();
|
|
}
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Subtracts specified number of years |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::YearDec(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta!=0)
|
|
{
|
|
year-=delta;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Adds specified number of years |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::YearInc(int delta)
|
|
{
|
|
//--- if increment is 0 - exit
|
|
if(delta!=0)
|
|
{
|
|
year+=delta;
|
|
//--- check if day is correct
|
|
DayCheck();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Checks if day number is correct |
|
|
//+------------------------------------------------------------------+
|
|
void CDateTime::DayCheck(void)
|
|
{
|
|
if(day>DaysInMonth())
|
|
day=DaysInMonth();
|
|
//--- this is required to get day of week and day of year
|
|
TimeToStruct(StructToTime(this),this);
|
|
}
|
|
//+------------------------------------------------------------------+
|