TimeUtils/validate.mq5
amrali eafea9ed87
2026-07-18 23:27:05 +03:00

172 lines
4.7 KiB
MQL5

//+------------------------------------------------------------------+
//| validate.mq5 |
//| Copyright © 2026, Amr Ali |
//| https://www.mql5.com/en/users/amrali |
//+------------------------------------------------------------------+
#include "TimeUtils.mqh"
#define TEST_SIZE 30000000
//ulong randUlong() { return((ulong)rand()<<60)|((ulong)rand()<<45)|((ulong)rand()<<30)|((ulong)rand()<<15)|(ulong)rand(); }
// RNG that can generate all possible 2^64 values.
struct SplitMix64 {
uint64_t x;
uint64_t next() {
uint64_t z = (x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
long next(long min, long max) {return min + (long)(next()%(max-min+1));} // [min, max]
void seed(uint64_t seed) { x = seed; } // custom seed (e.g., for reproducibility)
SplitMix64() { x = GetTickCount64(); } // auto-seeded constructor
};
void OnStart()
{
Print("\nTesting random times in the supported datetime range [1970.01.01, 3000.12.31]...");
long tested = 0;
const datetime minTime = D'1970.01.01';
const datetime maxTime = D'3000.12.31';
SplitMix64 sm64;
// for(datetime t = minTime; t <= maxTime; t += HOURSECS)
// {
for(int i = 0; i < TEST_SIZE; i++)
{
datetime t = (datetime)sm64.next(minTime, maxTime);
// MQL's reference function
MqlDateTime dt, myStruct;
TimeToStruct(t, dt);
// Validation of TimeToStructFast() function.
TimeToStructFast(t, myStruct);
if(dt.year != myStruct.year
|| dt.mon != myStruct.mon
|| dt.day != myStruct.day
|| dt.hour != myStruct.hour
|| dt.min != myStruct.min
|| dt.sec != myStruct.sec
|| dt.day_of_week != myStruct.day_of_week
|| dt.day_of_year != myStruct.day_of_year)
{
Print("TimeToStructFast mismatch at ", t);
MqlDateTime temp[2];
temp[0] = dt;
temp[1] = myStruct;
ArrayPrint(temp);
break;
}
// Validation of StructToTimeFast() function.
datetime myTime = StructToTimeFast(myStruct);
if(t != myTime)
{
Print("StructToTimeFast mismatch at ", t);
Print(t, " != ", myTime);
break;
}
// Validations of individual functions
int myYear = Year(t);
int myMonth = Month(t);
int myDay = Day(t);
int myHour = Hour(t);
int myMinute = Minute(t);
int mySecond = Second(t);
int myDOW = DayOfWeek(t);
int myDOY = DayOfYear(t);
if(dt.year != myYear)
{
Print("Year() mismatch at ", t);
Print(dt.year, " != ", myYear);
break;
}
if(dt.mon != myMonth)
{
Print("Month() mismatch at ", t);
Print(dt.mon, " != ", myMonth);
break;
}
if(dt.day != myDay)
{
Print("Day() mismatch at ", t);
Print(dt.day, " != ", myDay);
break;
}
if(dt.hour != myHour)
{
Print("Hour() mismatch at ", t);
Print(dt.hour, " != ", myHour);
break;
}
if(dt.min != myMinute)
{
Print("Minute() mismatch at ", t);
Print(dt.min, " != ", myMinute);
break;
}
if(dt.sec != mySecond)
{
Print("Second() mismatch at ", t);
Print(dt.sec, " != ", mySecond);
break;
}
if(dt.day_of_week != myDOW)
{
Print("DayOfWeek() mismatch at ", t);
Print(dt.day_of_week, " != ", myDOW);
break;
}
if(dt.day_of_year != myDOY)
{
Print("DayOfYear() mismatch at ", t);
Print(dt.day_of_year, " != ", myDOY);
break;
}
tested++;
if(tested % (TEST_SIZE/10) == 0)
{
Print(tested, " times checked...");
}
}
Print("\nFinished. Total random times tested: ", tested);
}
//+------------------------------------------------------------------+
/*
Testing random times in the supported datetime range [1970.01.01, 3000.12.31]...
3000000 times checked...
6000000 times checked...
9000000 times checked...
12000000 times checked...
15000000 times checked...
18000000 times checked...
21000000 times checked...
24000000 times checked...
27000000 times checked...
30000000 times checked...
Finished. Total random times tested: 30000000
*/