3
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ Can you show the input too please. \$\endgroup\$
    – Dangph
    Commented Apr 22, 2015 at 0:45
  • \$\begingroup\$ Done, as noted powershell might be flexible enough to handle various input formats but more testing is required to fully understand this. \$\endgroup\$ Commented Apr 22, 2015 at 1:01

1 Answer 1

3
\$\begingroup\$

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
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.