Search code examples
powershelldatetimeutcdatetime-conversion

PowerShell - Converting UTC To British Summer Time


I have written a simple function to convert any UTC time to current UK time (depending if Daylight Saving Time is being applied at the current season the result is either the same UTC or UTC + 1):

function Convert-UTCToUKTime
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true)] $UTCTime
    )
    $UKTime = (Get-Date -Date $UTCTime)
    if ($UKTime.IsDaylightSavingTime() -eq $true)
    {
        $UKTime = $UKTime.AddHours(1)
    }
    return $UKTime
}

I am also using this in the different function to get current UK time and it works just fine:

function Get-UKTime
{
    [CmdletBinding()]
    [OutputType([System.String])]
    param
    (
        [Parameter(Mandatory = $true)] [String] $Format
    )
    $UKTime = Convert-UTCToUKTime -Time ((Get-Date).ToUniversalTime())

    return $UKTime.ToString($Format)
}

However, when I try to pass the converting function a file created time (which is of course in UTC), it fails to recognize daylight saving time and therefore returns the UK time value with one hour behind (I tried to pass the exact same time by using Get-Date - there were no issues):

[System.IO.FileInfo] $FileInfo = $FullFileName
$FileCreatedTime = Convert-UTCToUKTime -UTCTime (($FileInfo.CreationTimeUTC)

I found the fix which helped me to get this working as I expect to (by converting the DateTime type to String before passing as a parameter):

$FileCreatedTime = Convert-UTCToUKTime -UTCTime (($FileInfo.CreationTimeUTC).ToString("yyyy/MM/dd hh:mm:ss"))

However, I am not really sure why this works. What is the difference here between using this with Get-Date and passing File Created time as a parameter as they both have the same DateTime type?

Any explanation would be really appreciated.


Solution

  • After extensive testing and discussion with peer colleagues, I think I have the answer to my original question now.

    First of all, thanks to @PetSerAl for suggesting to use the Microsoft defined 'GMT Standard Time' time zone, which me and other users in the community found to be named controversially bearing in mind actual GMT has different offset in real life (hence the confusion), however, I found it to be exactly what I need to use in my case.

    So why was I getting different results when passing the string and DateTime object of the same time in UTC? The answer is this:

    Once I passed the object to the function which was a result of getting the time from file creation stamp in UTC, it was automatically initiated as proper UTC time type object, having the property .Kind set to value UTC (there are only two valid values for this property - UTC and Local for everything else). The function getting this parameter initially recognized the UTC type time and it could not detect the daylight saving time as UTC time zone simply does not support it. In second case of sending the string to the function the main difference here was that once converting the actual string to the DateTime object inside my function it was using Get-Date, which by default instantiates the result object by using local machine's time (I am working in Lithuania) and therefore IsDaylightSavingTime() now could return the $True value as my local time zone does support it.