【问题标题】:Difficulties converting Hex String to DateTime将十六进制字符串转换为日期时间的困难
【发布时间】:2016-02-17 00:39:38
【问题描述】:

我正在尝试将通过不同应用程序提供的一些十六进制字符串转换为正确的 DateTime 值,但是无论我尝试什么,该值总是错误的。十六进制字符串来自多个系统的 ShutdownTime 注册表项,在读取时由不同的应用程序转换为十六进制。

这是我尝试过的代码:

$shutdownkey = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Windows\' -Name ShutdownTime

$bitconverted = [DateTime]::FromFileTime([System.BitConverter]::ToInt64($shutdownkey.ShutdownTime, 0))

$hextime = "C11E6DF46024D101"

$test = [DateTime]::FromFileTime([Convert]::ToInt64($hextime, 16))

所以当我使用例如我自己的 ShutdownTime 键时,前两行正常工作,但是当我使用最后两行或以下任何一个时:

C9520B970A69D101

0A44A6EA3300D101

C11E6DF46024D101

它要么失败,要么给我一个不可能的时间戳。但是,如果我使用DCode 之类的工具,它会成功地将其转换为“Windows:64 位十六进制值 - Little Endian”的解码格式。从我在几个地方读到的内容来看,.NET 使用小端,所以这不应该是编码的问题,但我怀疑它是。

谁能帮我弄清楚如何解决这个转换问题?这让我很烦恼,为什么我无法弄清楚这一点。

【问题讨论】:

标签: c# .net powershell datetime


【解决方案1】:

字节序是向后的。时代应该倒过来。例如:

C9520B970A69D101 should be 01D1690A970B52C9 
[DateTime]::FromFileTime(0x01D1690A970B52C9) gives (Tuesday, February 16, 2016 4:37:17 PM)

【讨论】:

  • 你将如何在 powershell 中翻转这个十六进制数字?是否有从/到编码的转换?
  • 一般其他问题应作为新问题发布。也就是说,您可以使用 [System.BitConverter] 类将 Uint64 转换为字节数组,反转数组 ([array]::reverse),然后将反转后的数组转换回 Uint64
  • 这正是我正在寻找的信息。 Anthony 的回应与我的后续行动相同,所以感谢你们俩!
【解决方案2】:

来自Read Registery value and convert to date 大卫布拉班特评论

$regKey = Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Windows
$shutDown = $regKey.ShutdownTime
$Int64Value = [System.BitConverter]::ToInt64($shutDown, 0)
$date = [DateTime]::FromFileTime($Int64Value)

$date

还有我的延伸

并非所有注册表项都直接转换为 DateTime。有些数组是复合的。

压缩函数

function GetRegDate ($path, $key){
    function GVl ($ar){
        return [uint32]('0x'+(($ar|ForEach-Object ToString X2) -join ''))
    }
    $ar=Get-ItemPropertyValue $path $key
    [array]::reverse($ar)
    $time = New-Object DateTime (GVl $ar[14..15]),(GVl $ar[12..13]),(GVl $ar[8..9]),(GVl $ar[6..7]),(GVl $ar[4..5]),(GVl $ar[2..3]),(GVl $ar[0..1])
    return $time
}
$path='HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\{6CB1FEAE-02B2-4922-8D81-331219215E21}'
$key='DateLastConnected'
$DateLastConnected=GetRegDate $path $key
Get-Date $DateLastConnected -Format "ddd, dd.MM.yyyy HH:mm:ss,fff"

原函数

# http://cfed-ttf.blogspot.com/2009/08/decoding-datecreated-and.html
$path='HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\{6CB1FEAE-02B2-4922-8D81-331219215E21}'
$key='DateLastConnected'
$dateArr=Get-ItemPropertyValue $path $key
[array]::reverse($dateArr)

$chank = '0x'+(($dateArr[0..1]|ForEach-Object ToString X2) -join '')
$mSeconds = [uint32]$chank

$chank = '0x'+(($dateArr[2..3]|ForEach-Object ToString X2) -join '')
$Seconds = [uint32]$chank

$chank = '0x'+(($dateArr[4..5]|ForEach-Object ToString X2) -join '')
$minutes = [uint32]$chank

$chank = '0x'+(($dateArr[6..7]|ForEach-Object ToString X2) -join '')
$hour = [uint32]$chank

$chank = '0x'+(($dateArr[8..9]|ForEach-Object ToString X2) -join '')
$date = [uint32]$chank

$chank = '0x'+(($dateArr[10..11]|ForEach-Object ToString X2) -join '')
$Weekday =[uint32]$chank
$WeekdayLong = (Get-UICulture).DateTimeFormat.GetDayName([uint32]$Weekday)

$chank = '0x'+(($dateArr[12..13]|ForEach-Object ToString X2) -join '')
$Month = [uint32]$chank
$LongMonth = (Get-UICulture).DateTimeFormat.GetMonthName([uint32]$Month)

$chank = '0x'+(($dateArr[14..15]|ForEach-Object ToString X2) -join '')
$Year = [uint32]$chank

$time = New-Object DateTime $Year, $Month, $date, $hour, $minutes, $Seconds, $mSeconds
Get-Date $time -Format "ddd, dd.MM.yyyy HH:mm:ss,fff"

【讨论】:

    【解决方案3】:

    有时十六进制字符串日期可以是 Unix 时间戳、UTC 时间戳等。 这里有一些快速转换可以尝试。

    $hexValue =0x61D75331
    [datetimeoffset]::FromUnixTimeSeconds([Convert]::ToInt64($hexValue)).datetime
    [datetime]::FromFileTime([Convert]::ToInt64($hexValue))
    [datetime]::FromFileTimeUtc([Convert]::ToInt64($hexValue))
    [datetime]::FromBinary([Convert]::ToInt64($hexValue))
    

    给予

    January 6, 2022 20:38:09 #was what I needed
    December 31, 1600 19:02:44
    January 1, 1601 00:02:44
    January 1, 0001 00:02:44
    

    【讨论】:

      猜你喜欢
      • 2022-09-29
      • 2018-01-31
      • 2018-01-22
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 2020-11-07
      相关资源
      最近更新 更多