TimeUtils/validate.mq5
2026-07-14 15:27:00 +03:00

169 lines
4.5 KiB
MQL5

//+------------------------------------------------------------------+
//| validate.mq5 |
//| Copyright © 2024, Amr Ali |
//| https://www.mql5.com/en/users/amrali |
//+------------------------------------------------------------------+
#include "TimeUtils.mqh"
#define TEST_SIZE 30000000
// RNG that can generate all possible 2^64 values.
struct SplitMix64 {
uint64_t x;
uint64_t next64() {
uint64_t z = (x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
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 sm;
// for(datetime t = minTime; t <= maxTime; t += HOURSECS)
// {
for(int i = 0; i < TEST_SIZE; i++)
{
datetime t = (datetime)(sm.next64() % maxTime);
// MQL's reference function
MqlDateTime st, myStruct;
TimeToStruct(t, st);
// Validation of TimeToStructFast() function.
TimeToStructFast(t, myStruct);
if(st.year != myStruct.year
|| st.mon != myStruct.mon
|| st.day != myStruct.day
|| st.hour != myStruct.hour
|| st.min != myStruct.min
|| st.sec != myStruct.sec
|| st.day_of_week != myStruct.day_of_week
|| st.day_of_year != myStruct.day_of_year)
{
Print("TimeToStructFast mismatch at ", t);
MqlDateTime temp[2];
temp[0] = st;
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(st.year != myYear)
{
Print("GetYear mismatch at ", t);
Print(st.year, " != ", myYear);
break;
}
if(st.mon != myMonth)
{
Print("GetMonth mismatch at ", t);
Print(st.mon, " != ", myMonth);
break;
}
if(st.day != myDay)
{
Print("GetDay mismatch at ", t);
Print(st.day, " != ", myDay);
break;
}
if(st.hour != myHour)
{
Print("GetHour mismatch at ", t);
Print(st.hour, " != ", myHour);
break;
}
if(st.min != myMinute)
{
Print("GetMinute mismatch at ", t);
Print(st.min, " != ", myMinute);
break;
}
if(st.sec != mySecond)
{
Print("GetSecond mismatch at ", t);
Print(st.sec, " != ", mySecond);
break;
}
if(st.day_of_week != myDOW)
{
Print("DayOfWeek mismatch at ", t);
Print(st.day_of_week, " != ", myDOW);
break;
}
if(st.day_of_year != myDOY)
{
Print("DayOfYear mismatch at ", t);
Print(st.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
*/