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);
| |||
}
| |||
//+------------------------------------------------------------------+
|