将Hex String转换为DateTime的困难

时间:2016-02-17 00:39:39

标签: c# .net powershell datetime

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

这是我尝试过的代码:

subset(df, x==111 & x-date=='2/2/2016', select = c(person,x,x-date))

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

C9520B970A69D101

0A44A6EA3300D101

C11E6DF46024D101

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

任何人都可以帮我弄清楚如何解决这个转换问题吗?这让我烦恼,为什么我无法理解这一点。

2 个答案:

答案 0 :(得分:5)

字节顺序落后。时间应该扭转。例如:

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

答案 1 :(得分:0)

来自Read Registery value and convert to date 大卫·布拉本特(David Brabant)评论

$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"