Convert list of UTC to Current TimeZone I found myself with a list of UTC timestamps and wanted to convert them into the local time zone.  Using this web post as a starting point, I modified the script to grab a text file containing UTC times (one per line) and loop over each one outputting the results in a nice two column format.

Is there a more efficient method for accomplishing this?  I've seen people mention the .NET method $UTC.ToLocalTime() but I didn't find details on that, so I went with my frankenstein script.

$UTCTime = GC "C:\Scripts\UTC.txt"
$results = '' | Select UTCTime,PST
Foreach ($newtime in $UTCTime){
$strCurrentTimeZone = (Get-WmiObject win32_timezone).StandardName
$TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone)
$LocalTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($newtime, $TZ)
$results.UTCTime = $newtime
$results.PST = $LocalTime
 $results
}




Input is: (and powershell might be flexible enough to handle various input formatting, more testing is needed to determine this)

4/19/2015 4:10:03 AM
4/19/2015 9:10:03 AM


Output is:


UTCTime               PST                  
-------               ---                  
4/19/2015 4:10:03 AM  4/18/2015 9:10:03 PM
4/19/2015 9:10:03 AM  4/19/2015 2:10:03 AM
This is how I would do it. First, we need a function to convert a UTC string to a DateTime since one doesn't already exist, as you already found out. The function that you found looks a bit complicated to me. I did a search for ".net utc to local time", and I found this: https://stackoverflow.com/questions/179940/convert-utc-gmt-time-to-local-time

Don't forget that .NET code, such as C#, can be translated easily into PowerShell. This is what I came up with, based on the top-rated answer:

function UtcToDateTime($dateStr)
{
    $date = [DateTime]::Parse($dateStr)
    [DateTime]::SpecifyKind($date, [DateTimeKind]::Utc)
}


The result is returned in the last line of that function because SpecifyKind returns a result.

Now we can use that function to transform our UTC date strings into DateTime objects:

$utcTimes = gc C:\Scripts\UTC.txt

$dates = $utcTimes | % { UtcToDateTime $_ }


The % is short for foreach. In English: "for each date in $dates, convert it to a DateTime using our function."

Since you want a two-column output, an easy way to do that is to make a custom objects with two the desired two fields:

$results = $dates | 
    % { [pscustomobject]@{UTCTime = $_.ToString(); LocalTime = $_.ToLocalTime().ToString() } }


The @{...} is a hash table. So what that code says is that for each date, convert it to a hash table, and then convert that hash table into a pscustomobject. (That's just an easy way to make custom objects.)

And now we return our results:

$results


Which looks like the following (note that days and months are switched in my country):

UTCTime                  LocalTime            
-------                  ---------            
19/04/2015 4:10:03 AM    19/04/2015 2:10:03 PM
19/03/2015 9:10:03 AM    19/03/2015 7:10:03 PM


Here's the full script:

function UtcToDateTime($dateStr)
{
    $date = [DateTime]::Parse($dateStr)
    [DateTime]::SpecifyKind($date, [DateTimeKind]::Utc)
}

$utcTimes = gc C:\Scripts\UTC.txt

$dates = $utcTimes | % { UtcToDateTime $_ }

$results = $dates | 
    % { [pscustomobject]@{UTCTime = $_.ToString(); LocalTime = $_.ToLocalTime().ToString() } }

$results