Get Windows 32-bit formatted Time/Date in PowerShell

Viewed 165

Is there a PowerShell command for retrieving the current datetime as a value encoded in the Windows C Runtime 32-Bit Time/Date Format?

2 Answers

I am not aware of an already existing function for that. You can do it manually like this:

$date = Get-Date
[uint16]$encodedTime = (((($date.Hour) -shl 6) + $date.Minute) -shl 5) + $date.Second / 2
[uint16]$encodedDate = (((($date.Year - 1980) -shl 4) + $date.Month) -shl 5) + $date.Day

You can combine these values further, if needed:

[uint32]$encodedTimeDate = $encodedTime -shl 16 + $encodedDate
[uint32]$encodedDateTime = $encodedDate -shl 16 + $encodedTime

To complement stackprotector's excellent answer, I used his code to create two helper functions to convert to and -from a dos datetime value:

function ConvertTo-DosDateTime {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [DateTime]$Date = (Get-Date)
    )
    # seconds are stored divided by 2
    [uint16]$encodedTime = (((($Date.Hour) -shl 6) + $Date.Minute) -shl 5) + ($Date.Second -shr 1)
    [uint16]$encodedDate = (((($Date.Year - 1980) -shl 4) + $Date.Month) -shl 5) + $Date.Day
    ([uint32]$encodedDate -shl 16) + $encodedTime
}

function ConvertFrom-DosDateTime {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [uint32]$DosDate
    )
    # split the 4 bytes into a date and a time part
    [uint32]$encodedDate = $DosDate -shr 16
    [uint32]$encodedTime = $DosDate -band 0xffff
    # shift and mask-off the relevant bits
    $day   = $encodedDate -band 0x1f                    # 5 bits  (0-4)
    $month = ($encodedDate -shr 5) -band 0xf            # 4 bits  (5-8)
    $year  = (($encodedDate -shr 9) -band 0x7f) + 1980  # 7 bits  (9-15)
    # same for the time part
    $secs  = ($encodedTime -band 0x1f) * 2              # 5 bits  (0-4)
    $mins  = ($encodedTime -shr 5) -band 0x3f           # 6 bits  (5-10)
    $hrs   = ($encodedTime -shr 11) -band 0x1f          # 5 bits  (11-15)

    # return as DateTime object
    Get-Date -Year $year -Month $month -Day $day -Hour $hrs -Minute $mins -Second $secs -Millisecond 0
}

All credits to stackprotector of course.

Related