TimeUtils/CalendarValidation/GenerateCases.mq5

237 lines
5.8 KiB
MQL5
Raw Permalink Normal View History

2026-07-15 02:45:49 +03:00
//+------------------------------------------------------------------+
//| GenerateCases.mq5 |
//| CalendarDifference Test Generator |
//+------------------------------------------------------------------+
#property script_show_inputs
#include "..\TimeUtils.mqh"
input int RandomPairs = 100000;
const datetime MIN_TIME = D'1970.01.01 00:00:00';
const datetime MAX_TIME = D'3000.12.31 23:59:59';
//---------------------------------------------------------------
// SplitMix64
//---------------------------------------------------------------
struct SplitMix64
{
ulong state;
SplitMix64()
{
state = (ulong)GetTickCount64();
}
ulong Next()
{
ulong z = (state += 0x9E3779B97F4A7C15);
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9;
z = (z ^ (z >> 27)) * 0x94D049BB133111EB;
return z ^ (z >> 31);
}
};
SplitMix64 RNG;
//---------------------------------------------------------------
string ISO(datetime t)
{
MqlDateTime s;
TimeToStructFast(t, s);
return StringFormat("%04d-%02d-%02dT%02d:%02d:%02d",
s.year,
s.mon,
s.day,
s.hour,
s.min,
s.sec);
}
//---------------------------------------------------------------
void WritePair(int file,
datetime from,
datetime to)
{
MqlDateTime diff;
CalendarDifference(from, to, diff);
FileWrite(file,
ISO(from),
ISO(to),
diff.year,
diff.mon,
diff.day,
diff.hour,
diff.min,
diff.sec);
}
//+------------------------------------------------------------------+
//| Writes the pair only if both timestamps are in range |
//+------------------------------------------------------------------+
void WritePairIfValid(const int file,
const datetime from,
const datetime to)
{
if(to < MIN_TIME || to > MAX_TIME)
return;
WritePair(file, from, to);
}
//---------------------------------------------------------------
datetime RandomTime()
{
ulong span = (ulong)(MAX_TIME - MIN_TIME);
return (datetime)(MIN_TIME + (datetime)(RNG.Next() % span));
}
//---------------------------------------------------------------
void GenerateMonthEnds(int file)
{
for(int year=1970; year<=3000; year++)
{
for(int month=1; month<=12; month++)
{
int last=DaysInMonth(year,month);
for(int day=MathMax(1,last-3); day<=last; day++)
{
datetime t=DateFrom(year,month,day);
WritePairIfValid(file, t, AddDays(t, -2));
WritePairIfValid(file, t, AddDays(t, -1));
WritePairIfValid(file, t, AddDays(t, 1));
WritePairIfValid(file, t, AddDays(t, 2));
WritePairIfValid(file, t, AddMonths(t, -1));
WritePairIfValid(file, t, AddMonths(t, 1));
WritePairIfValid(file, t, AddYears(t, -1));
WritePairIfValid(file, t, AddYears(t, 1));
}
}
}
}
//---------------------------------------------------------------
void GenerateLeapYears(int file)
{
for(int year=1970; year<=3000; year++)
{
if(!IsLeapYear(year))
continue;
datetime feb28=DateFrom(year,2,28);
WritePairIfValid(file,feb28,AddDays(feb28,1));
WritePairIfValid(file,feb28,AddDays(feb28,2));
datetime feb29=DateFrom(year,2,29);
WritePairIfValid(file,feb29,AddYears(feb29,1));
WritePairIfValid(file,feb29,AddYears(feb29,4));
WritePairIfValid(file,feb29,AddMonths(feb29,12));
}
}
//---------------------------------------------------------------
void GenerateYearBoundaries(int file)
{
for(int year=1970; year<=3000; year++)
{
datetime end=DateFrom(year,12,31,23,59,59);
WritePairIfValid(file,end,AddSeconds(end,1));
WritePairIfValid(file,end,AddDays(end,1));
WritePairIfValid(file,end,AddMonths(end,1));
WritePairIfValid(file,end,AddYears(end,1));
}
}
//---------------------------------------------------------------
void GenerateQuarterBoundaries(int file)
{
const int months[]={3,6,9,12};
for(int year=1970; year<=3000; year++)
{
for(int i=0;i<4;i++)
{
int month=months[i];
datetime t=DateFrom(
year,
month,
DaysInMonth(year,month));
WritePairIfValid(file,t,AddDays(t,1));
WritePairIfValid(file,t,AddMonths(t,3));
}
}
}
//---------------------------------------------------------------
void GenerateRandom(int file)
{
for(int i=0;i<RandomPairs;i++)
{
WritePairIfValid(file,
RandomTime(),
RandomTime());
}
}
//---------------------------------------------------------------
void OnStart()
{
int file = FileOpen(
"CalendarDifferenceCases.csv",
FILE_WRITE | FILE_CSV | FILE_ANSI,
','
);
if(file == INVALID_HANDLE)
{
Print("FileOpen() failed. Error = ", GetLastError());
return;
}
FileWrite(file,
"from",
"to",
"years",
"months",
"days",
"hours",
"minutes",
"seconds");
GenerateMonthEnds(file);
GenerateLeapYears(file);
GenerateQuarterBoundaries(file);
GenerateYearBoundaries(file);
GenerateRandom(file);
FileClose(file);
Print("CalendarDifferenceCases.csv generated.");
}