server 发表于 2025-5-18 23:44:10

来个屌大的解释一下,我还是搞不懂,那种方式更快。。

本帖最后由 server 于 2025-5-19 00:15 编辑

有问题吗??

<火山程序 类型 = "通常" 版本 = 1 />

方法 取现行时间2 <类型 = 小数 折叠 @禁止流程检查 = 真>
{
    @   FILETIME ftUtc, ftLocal;
    @   ::GetSystemTimeAsFileTime(&ftUtc);
    @   if (!::FileTimeToLocalFileTime(&ftUtc, &ftLocal)) {return 0; }
    @   ULARGE_INTEGER uli;
    @   uli.LowPart = ftLocal.dwLowDateTime;
    @   uli.HighPart = ftLocal.dwHighDateTime;
    @   return static_cast<DOUBLE>(uli.QuadPart - 109205ULL * 864000000000ULL) / 864000000000.0;

}

<火山程序 类型 = "通常" 版本 = 1 />

方法 _取本地时间NT <公开 静态 类型 = 小数 折叠2 @视窗.外部头文件 = "winternl.h" @视窗.外部库 = "ntdll.lib" @禁止流程检查 = 真>
{

    @ LARGE_INTEGER SystemTime = {0};
    @ if(NtQuerySystemTime(&SystemTime) == 0){
    @   FILETIME ft_utc, ft_local;
    @   ft_utc.dwLowDateTime = SystemTime.LowPart;
    @   ft_utc.dwHighDateTime = SystemTime.HighPart;
    @   if(FileTimeToLocalFileTime(&ft_utc, &ft_local)) {
    @         return static_cast<double>(((((ULONGLONG)ft_local.dwHighDateTime << 32) | ft_local.dwLowDateTime)-109205ULL * 864000000000ULL)) / 864000000000.0;
    @   }
    @ }
    @ return 0;

}



下面是火山官方的写法:

DOUBLE GetCurrentDateTime ()
{
    SYSTEMTIME st;
    ::GetLocalTime (&st);

    return ToDate ((INT_P)(UINT_P)st.wYear, (INT_P)(UINT_P)st.wMonth, (INT_P)(UINT_P)st.wDay, (INT_P)(UINT_P)st.wHour, (INT_P)(UINT_P)st.wMinute, (INT_P)(UINT_P)st.wSecond, (INT_P)(UINT_P)st.wMilliseconds, _VOL_MIN_DATE);
}


DOUBLE ToDate (INT_P npYear, INT_P npMonth, INT_P npDay, INT_P npHour, INT_P npMinute, INT_P npSecond, INT_P npMillSecond, const DOUBLE dbDateFailed)
{
    npYear = CLIP (npYear, 100, 9999);
    npMonth = CLIP (npMonth, 1, 12);
    npDay = CLIP (npDay, 1, 31);
    npHour = CLIP (npHour, 0, 23);
    npMinute = CLIP (npMinute, 0, 59);
    npSecond = CLIP (npSecond, 0, 59);
    npMillSecond = CLIP (npMillSecond, 0, 999);

    const INT_P npDaysOfMonth = GetDaysOfMonth (npYear, npMonth);
    npDay = MIN (npDaysOfMonth, npDay);

    //---------------------------------------------------------------------------------

    SYSTEMTIME st;
    ZERO_MEM (&st, sizeof (SYSTEMTIME));
    st.wYear = (WORD)npYear;
    st.wMonth = (WORD)npMonth;
    st.wDay = (WORD)npDay;
    st.wHour = (WORD)npHour;
    st.wMinute = (WORD)npMinute;
    st.wSecond = (WORD)npSecond;
    st.wMilliseconds = 0;// SystemTimeToVariantTime没有处理毫秒字段

    DOUBLE dbDate;
    if (::SystemTimeToVariantTime (&st, &dbDate) == FALSE)
      return dbDateFailed;

    return dbDate + (DOUBLE)npMillSecond / (1000.0 * 60.0 * 60.0 * 24.0);// 手动将毫秒字段添加进去

    /*if (::SystemTimeToVariantTime (&st, &dbDate) == FALSE)
      return dbDateFailed;

    ZERO_MEM (&st, sizeof (SYSTEMTIME));
    if (::VariantTimeToSystemTime (dbDate, &st) == FALSE)
      return dbDateFailed;

    return (((INT_P)st.wYear == npYear &&
            (INT_P)st.wMonth == npMonth &&
            (INT_P)st.wDay == npDay &&
            (INT_P)st.wHour == npHour &&
            (INT_P)st.wMinute == npMinute &&
            (INT_P)st.wSecond == npSecond) ? dbDate : dbDateFailed); */
}

Xelloss0618 发表于 2025-5-19 00:39:07

你跑一下性能测试不就知道了,前面的当然更快,官方那个写得太复杂。
GetSystemTimeAsFileTime 也比 NtQuerySystemTime 快,这两个的作用是一样的。
FILETIME的精度也更高,可以到100纳秒,官方那个只能到毫秒。
如果是输出时间戳的话,FILETIME可以更快,保留精度也更多。
页: [1]
查看完整版本: 来个屌大的解释一下,我还是搞不懂,那种方式更快。。