NSIS中实现时间戳和 FILETIME 互相转换

NSIS中实现时间戳和 FILETIME 互相转换

nsisfans
2022-01-14 / 0 评论 / 130 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年01月14日,已超过507天没有更新,若内容或图片失效,请留言反馈。

在实际应用中,我们经常会遇到时间戳和 FILETIME 互相转换的需求,贾可同学实现方法如下:

Name "Example"
OutFile "Example.exe"

#LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf"
#LoadLanguageFile "${NSISDIR}\Contrib\Language files\TradChinese.nlf"
#LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf"

#SetFont "MS Shell Dlg" 8

RequestExecutionLevel user

Page instfiles

InstallColors /windows
ShowInstDetails show
XPStyle on

Section "-"

    # 调用 GetSystemTimeAsFileTime 获取系统时间的格式为 Windows FILETIME ($R2)
    System::Call "kernel32::GetSystemTimeAsFileTime(*l.R2)"
    DetailPrint $R2
    # 调用 FileTimeToLocalFileTime 将 UTC FILETIME ($R2) 转为本机 FILETIME ($R2)
    # 默认时间戳代表的时间为 UTC 时间,如果不需要转本机时间则不需要下一行。
    System::Call "kernel32::FileTimeToLocalFileTime(*lR2,*l.R2)"
    DetailPrint $R2

    ############################################################################
    # 将 FILETIME 转换为时间戳方法一:
    ############################################################################

    # 调用 RtlTimeToSecondsSince1970 将 Windows FILETIME ($R2) 转为 timestamp ($R1)
    System::Call "ntdll::RtlTimeToSecondsSince1970(*lR2,*i.R1)"
    DetailPrint $R1

    ############################################################################
    # 将 FILETIME 转换为时间戳方法二:
    ############################################################################

    #
    # 通过以下公式将 Windows FILETIME ($R2) 计算为 timestamp ($R1)
    #
    # timestamp = (FILETIME - 116444736000000000) / 10000000
    # 或:
    # timestamp = (FILETIME / 10000000) - 11644473600
    #
    # 调用 System::Int64Op 计算...
    System::Int64Op $R2 - 116444736000000000
    Pop $R1
    System::Int64Op $R1 / 10000000
    Pop $R1

    DetailPrint $R1

SectionEnd

#
# 将 FILETIME ($R2) 转换为具体的年月日输出出来
#
Function PrintFileTimeAsDateTime

    System::Call "*(&i2,&i2,&i2,&i2,&i2,&i2,&i2,&i2)p.R0"
    System::Call "kernel32::FileTimeToSystemTime(*lR2,pR0)"
    System::Call "*$R0(&i2.R1,&i2.R2,&i2,&i2.R3,&i2.R4,&i2.R5,&i2.R6,&i2.R7)"
    System::Free $R0

    IntFmt $R1 "%04u" $R1
    IntFmt $R2 "%02u" $R2
    IntFmt $R3 "%02u" $R3
    IntFmt $R4 "%02u" $R4
    IntFmt $R5 "%02u" $R5
    IntFmt $R6 "%02u" $R6
    IntFmt $R7 "%03u" $R7

    DetailPrint "$R1-$R2-$R3 $R4:$R5:$R6.$R7"

FunctionEnd

Section "-"

    ############################################################################
    # 将时间戳转换为 FILETIME 方法一:
    ############################################################################
    StrCpy $R1 1625068800

    # 调用 RtlSecondsSince1970ToTime 将 timestamp ($R1) 转为 Windows FILETIME ($R2)
    System::Call "ntdll::RtlSecondsSince1970ToTime(iR1,*l.R2)"
    # 调用 FileTimeToLocalFileTime 将 UTC FILETIME ($R2) 转为本机 FILETIME ($R2)
    # 默认时间戳代表的时间为 UTC 时间,如果不需要转本机时间则不需要下一行。
    System::Call "kernel32::FileTimeToLocalFileTime(*lR2,*l.R2)"

    # 将 FILETIME 转换为年月日输出
    Call PrintFileTimeAsDateTime

    ############################################################################
    # 将时间戳转换为 FILETIME 方法二:
    ############################################################################
    StrCpy $R1 1625068800

    #
    # 通过以下公式将 timestamp ($R1) 计算为 Windows FILETIME ($R2)
    #
    # FILETIME = (timestamp * 10000000 + 116444736000000000)
    # 或:
    # FILETIME = (timestamp + 11644473600) * 10000000
    #
    # 调用 System::Int64Op 计算...
    System::Int64Op $R1 + 11644473600
    Pop $R2
    System::Int64Op $R2 * 10000000
    Pop $R2

    # 将 FILETIME 转换为年月日输出
    Call PrintFileTimeAsDateTime

SectionEnd
0

评论 (0)

取消