When I started to use WinAPI datetime - I found many classes and several functions, but didn't find an explanation for simple operations with datetime. I describe here two operations:
- Difference between two datetimes (datetime2-datetime1) and receiving weeks, days, hours, elapsed between them.
- Add/Subtract weeks, days, hours, to/from datetime and receiving new datetime.
With WinAPI we receive more then 29 thousand years for manipulation (start from 01.01.1601). To be more exact - 0x8000000000000000 100-nanoseconds intervals == from zero [01 Jan 1601, 00:00:00] to 0x800...-1 [14 sep 30828, 02:48:05] where (1 sec = 1.000.000.000 nanoseconds)
WinAPI has two structs to store datetime -
SYSTEMTIME. It was a surprise for me but
SYSTEMTIME is only representation of datetime and for real operations with datetime we need to use
FILETIME. (why did Microsoft title it FILE ? where is the logic ?)
Why do I say that
SYSTEMTIME is only a representation? Look at this:
typedef struct _SYSTEMTIME
What do you see? Right - nothing says to us that
SYSTEMTIME is ONLY a representation. But if you receive datetime to
and make such operation as add 100 days:
st.wDay += 100;
and than try to receive string representation of this new date:
"yyyy MM dd",
You receive nothing.
GetLastError returns number of error,
GetDateFormat return 0. Of course, if you assign to
wDay number valid for
wMonth, you receive expected result (example - for Feb 2003 valid days from 1 to 28, if you assign
wDay=29 you receive nothing). So, conclusion -
SYSTEMTIME is not for above mentioned operations.
Ok, let us move to
FILETIME contains two
typedef struct _FILETIME
FILETIME to store 64 bit values. Value of
FILETIME is equal to number of 100-nanosecond intervals since 01 Jan 1601, 00:00:00. So, if (
FILETIME == 0) than we have 01 Jan 1601, 00:00:00. If (
FILETIME == 10000000*60*60*24) we have 02 Jan 1601, 00:00:00.
(1 sec = 10000000 (100 nanoseconds) - in one min 60 secs, in one hour 60 mins and in one day 24 hours
64 bit value means that we can store 0xFFFFFFFFFFFFFFFF intervals ! But manipulate only 0x800..., in two times less. This restriction is superimposed by
FileTimeToSystemTime. Read help:
FileTimeToSystemTime function only works with
FILETIME values that are less than 0x8000000000000000.
I think internals of this function use double (for convert to store double we need SIGNED
__int64), and we lose 1 bit to sign, and receive in two times less max value. But I think it is not a tragedy - 29 thousand is enough.
Go to algorithms
const __int64 nano100SecInWeek=(__int64)10000000*60*60*24*7;
const __int64 nano100SecInDay=(__int64)10000000*60*60*24;
const __int64 nano100SecInHour=(__int64)10000000*60*60;
const __int64 nano100SecInMin=(__int64)10000000*60;
const __int64 nano100SecInSec=(__int64)10000000;
const __int64 datepart,
const SYSTEMTIME* pst1,
const SYSTEMTIME* pst2
pi1 = (__int64*)&ft1;
pi2 = (__int64*)&ft2;
return (CompareFileTime(&ft1,&ft2)==1) ?
(((*pi1)-(*pi2))/(double)datepart) : (((*pi2)-(*pi1))/(double)datepart);
const __int64 datepart,
const __int64 num,
const SYSTEMTIME* pst
pi = (__int64*)&ft;
(*pi) += (__int64)num*datepart;
SAMPLE use of functions
"yyyy MM dd", buff,
printf("20031201 - 1 day = %s\n",buff);
These functions can't be used for work with month, quarter, year because it they are not constants. For work with such time intervals you need to modify the above algorithms.