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 than 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 a 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 then try to receive
string representation of this new date:
"yyyy MM dd",
You receive nothing.
GetLastError returns number of error,
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 the 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.
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.