65.9K
CodeProject 正在变化。 阅读更多。
Home

SystemTime 转 VariantTime(带毫秒)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.06/5 (8投票s)

2007年2月9日

3分钟阅读

viewsIcon

87073

downloadIcon

1806

增强的系统时间/变体时间转换,带毫秒

引言

当您使用 Microsoft Automation 函数 VariantTimeToSystemTime 将变体时间转换为系统时间,以及使用 SystemTimeToVariantTime 将系统时间转换为变体时间时,毫秒值会显示为零或被忽略。 这是一个已知问题,记录在 MSDN 知识库中,ID 为 Q297463。 但是,很多时候,忽略毫秒不是一个选择。 可以使用两个简单的函数包装原始 API 函数,以转换 SystemTimeVariantTime 反之亦然,而不会丢失毫秒信息。

示例应用程序只是为了演示这些函数的用法。 您可以输入 SystemTime 条目并单击转换以查看等效的 VariantTime,或者您可以输入 VariantTime 值并选择转换 Type 进行反向转换并将其转换回 SystemTime。 单击“GetCurrentTime”按钮将从系统上的当前时间填充 SystemTime 结构。 该应用程序还对您可以指定的输入范围进行一些基本验证。

Using the Code

函数 SystemTimeToVariantTimeWithMillisecondsVariantTimeToSystemTimeWithMilliseconds 可以替换 Microsoft Automation 函数,并且可以返回与原始函数相似的结果,而不会丢失毫秒信息。

a) SystemTimeToVariantTimeWithMillisecondssystemtime 作为输入,并将没有毫秒信息的信息传递给 Microsoft Automation 函数。 结果将是不带毫秒的转换后的变体时间。 不将毫秒信息传递给 Microsoft Automation 函数的原因是该函数会自动将该值四舍五入到最接近的秒,这不是我们想要的。 然后,我们添加毫秒的变体部分。

变体时间存储为 8 字节实数值(双精度),表示 1753 年 1 月 1 日至 2078 年 12 月 31 日(含)之间的日期。 值 2.0 表示 1900 年 1 月 1 日; 3.0 表示 1900 年 1 月 2 日,依此类推。 将值加 1 会将日期增加一天。 该值的小数部分表示一天中的时间。 因此,2.5 表示 1900 年 1 月 1 日中午; 3.25 表示 1900 年 1 月 2 日凌晨 6:00,依此类推。 因此,0.5 表示 12 小时,即 12*60*60 秒,因此 1 秒 = 0.5/(12*60*60) = .0000115740740740

BOOL CSysTimeConversionDlg::SystemTimeToVariantTimeWithMilliseconds 
                 (/*input*/ SYSTEMTIME st, /*output*/double *dVariantTime)
{
    BOOL retVal = TRUE;

    WORD wMilliSeconds = st.wMilliseconds; // save the milli second 
                                           // information
    st.wMilliseconds = 0; // pass 0 milliseconds to the function and get  
                          // the converted value without milliseconds
    double dWithoutms;
    retVal = SystemTimeToVariantTime(&st, &dWithoutms) ;

    // manually convert the millisecond information into variant 
    // fraction and add it to system converted value
    double OneMilliSecond = ONETHOUSANDMILLISECONDS/1000 ;
    *dVariantTime = dWithoutms + (OneMilliSecond * wMilliSeconds);

    return retVal;
}

b) VariantTimeToSystemTimeWithMilliseconds 接收变体时间,并单独计算 SYSTEMTIME 的每个组成部分,直到毫秒,因此将具有宝贵的毫秒信息。 我们首先使用 Microsoft Automation 函数 VariantTimeToSystemTime 从系统时间为我们提供变体时间。 我们从原始变体时间中删除 0.5 秒,以便消除 VariantTimeToSystemTime 函数的舍入问题。 然后,我们从分数计算 systemtime 的每个组成部分,直到获得毫秒信息。 一旦我们有了毫秒信息,我们就添加 0.5 秒来补偿我们之前的调整。

BOOL CSysTimeConversionDlg::VariantTimeToSystemTimeWithMilliseconds 
                  (/*input*/ double dVariantTime, /*output*/SYSTEMTIME *st)
{
    BOOL retVal = TRUE;

    double halfsecond = ONETHOUSANDMILLISECONDS / 2.0; 
    // ONETHOUSANDMILLISECONDS is equal to 0.0000115740740740

    retVal = VariantTimeToSystemTime(dVariantTime - halfsecond, st); 
    // this takes care of rounding problem with 
    // VariantTimetoSystemTime function
    if (retVal == FALSE)
    {
        return retVal;
    }

    double fraction = dVariantTime - (int) dVariantTime; 
    // extracts the fraction part

    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; // rounding off millisecond to the 
                                       // nearest millisecond 
    if (milliseconds < 1.0 || milliseconds > 999.0) //Fractional 
                          // calculations may yield in results like
        milliseconds = 0; // 0.00001 or 999.9999 which should actually 
                          // be zero (slightly above or below limits 
                          // are actually zero)

    if (milliseconds) 
        st->wMilliseconds = (WORD) milliseconds;
    else  // if there is 0 milliseconds, then we don't have the problem !!
        retVal = VariantTimeToSystemTime(dVariantTime, st); // 

    return retVal;
}

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.