## Introduction

When you use the Microsoft Automation functions `VariantTimeToSystemTime`

to convert variant time to system time and the `SystemTimeToVariantTime`

to convert system time to variant time, the milliseconds value appears as zero or is ignored. This is known issue documented in MSDN knowledge base, under ID Q297463. However many times ignoring milliseconds is not a option. Two simple functions wrapping the original API functions can be used to convert `SystemTime `

to `VariantTime `

and vice versa without loosing the millisecond information.

The Sample application is just to demonstrate the use of these functions. You can type in the `SystemTime `

entries and click convert to see the equivalent VariantTime or you can type in a `VariantTime `

value and select conversion `Type `

for reverse conversion and convert it back to `SystemTime`

. Clicking on the 'GetCurrentTime' button will populate `SystemTime `

structure from the current time on your system. The application also does some basic validations on the range of input you can specify.

## Using the code

Two functions which `SystemTimeToVariantTimeWithMilliseconds`

and `VariantTimeToSystemTimeWithMilliseconds`

can replace the Microsoft Automation functions and can return the result in a similar to the original functions without losing the millisecond information.

a) `SystemTimeToVariantTimeWithMilliseconds`

takes systemtime as the input and passes the information without millisecond information to the Microsoft Automation function. The result would be the converted variant time without milliseconds. The reason for not passing the millisecond information to the Microsoft Automation function is that the function automatically rounds off the value to the nearest second, which we don't want. We then add the variant portion for the millisecond.

A variant time is stored as an 8-byte real value (double), representing a date between January 1, 1753 and December 31, 2078, inclusive. The value 2.0 represents January 1, 1900; 3.0 represents January 2, 1900, and so on. Adding 1 to the value increments the date by a day. The fractional part of the value represents the time of day. Therefore, 2.5 represents noon on January 1, 1900; 3.25 represents 6:00 A.M. on January 2, 1900, and so on. So, 0.5 represents 12 hours i.e. 12*60*60 seconds, hence 1 second = 0.5/(12*60*60) = .0000115740740740

BOOL CSysTimeConversionDlg::SystemTimeToVariantTimeWithMilliseconds
( SYSTEMTIME st, double *dVariantTime)
{
BOOL retVal = TRUE;
WORD wMilliSeconds = st.wMilliseconds; st.wMilliseconds = 0; double dWithoutms;
retVal = SystemTimeToVariantTime(&st, &dWithoutms) ;
double OneMilliSecond = ONETHOUSANDMILLISECONDS/1000 ;
*dVariantTime = dWithoutms + (OneMilliSecond * wMilliSeconds);
return retVal;
}

b) `VariantTimeToSystemTimeWithMilliseconds`

takes in the variant time and calculates each component of `SYSTEMTIME`

individually down to the milliseconds and thus will have the precious millisecond information. We start with using the Microsoft Automation function `VariantTimeToSystemTime`

to give us the variant time from system time. We delete 0.5 seconds from the original variant time so that we remove the rounding off problem with `VariantTimeToSystemTime`

function. We then calculate each component of the systemtime from the fraction until we obtain the millisecond information. Once we have the millisecond information, we then add 0.5 second to compensate for our earlier adjustment.

BOOL CSysTimeConversionDlg::VariantTimeToSystemTimeWithMilliseconds
( double dVariantTime, SYSTEMTIME *st)
{
BOOL retVal = TRUE;
double halfsecond = ONETHOUSANDMILLISECONDS / 2.0;
retVal = VariantTimeToSystemTime(dVariantTime - halfsecond, st);
if (retVal == FALSE)
{
return retVal;
}
double fraction = dVariantTime - (int) dVariantTime;
double hours;
hours = fraction = (fraction - (int)fraction) * 24;
double minutes;
minutes = (hours - (int)hours) * 60;
double seconds;
seconds = (minutes - (int)minutes) * 60;
double milliseconds;
milliseconds = (seconds - (int)seconds) * 1000;
milliseconds = milliseconds + 0.5; if (milliseconds < 1.0 || milliseconds > 999.0) milliseconds = 0;
if (milliseconds)
st->wMilliseconds = (WORD) milliseconds;
else retVal = VariantTimeToSystemTime(dVariantTime, st);
return retVal;
}