Tuesday, March 27, 2018

Get weird time zones in PowerShell

There are weird time zones where the offset is not a round number of hours. If you are wondering where they are, we can find out with a single PowerShell line.

Windows has to work anywhere. So Microsoft keeps it up to date with all of the various time zones in the world. A “time zone” is not just the offset from UTC; it also includes the local rules for daylight saving time. As of this writing, there are 136 different time zone definitions recognized by Windows.

Windows stores these settings in the registry, but we can most easily get them using the .GetSystemTimeZones() static method of the [System.TimeZoneInfo] object.


This results in an array of TimeZoneInfo objects.

The TimeZoneInfo property .BaseUtcOffset holds the information we are looking for today. We only want those time zones with an odd offset. .BaseUtcOffset is a [TimeSpan] object. TimeSpan objects have a property called .TotalMinutes. We want those time zones whose .BaseUtcOffset is not a multiple of 60.

We can test an offset by using the % modulus operator to get the remainder of a division. (For math geeks, the % operator returns a remainder, not a modulus. For computer geeks, you can go back to thinking these are the same thing.)

When converting an integer to a [Boolean] $True or $False, zero converts to $False, and everything else converts to $True.

We combine these facts to create a filter that gives us only the time zones with unusual offsets.

[System.TimeZoneInfo]::GetSystemTimeZones() |
    Where-Object { $_.BaseUtcOffset.TotalMinutes % 60 }

And then we select specific properties to make the list more readable.

[System.TimeZoneInfo]::GetSystemTimeZones() |
    Where-Object { $_.BaseUtcOffset.TotalMinutes % 60 } |
    Select-Object -Property IdBaseUtcOffset

See also
It’s always 5 o-clock somewhere: Using .Net and PowerShell’s Extended Type System to find out where

No comments:

Post a Comment