0

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.

Aatif Akhter
  • 2,126
  • 1
  • 25
  • 46
Arnoldas Bendoraitis
  • 1,055
  • 1
  • 11
  • 17
  • `[TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($UTCTime,'UTC','GMT Standard Time')` – user4003407 Sep 09 '16 at 17:31
  • @PSA, GMT is NOT 'UK' time – Jaqueline Vanek Sep 09 '16 at 19:52
  • @JaquelineVanek Does you not have London here `[TimeZoneInfo]::FindSystemTimeZoneById('GMT Standard Time').DisplayName`? Is London not UK anymore? – user4003407 Sep 09 '16 at 20:16
  • @PetSerAl, Jaqueline is right, GMT is not exactly the same as 'UK time zone'. GMT is the same as UTC (and I wouldn't need to convert it) which does not support Daylight Saving Time being introduced from the last Sunday in March until the last Sunday in October, i.e. this time around BST (British Summer Time) is in play which is 1 hour ahead of GMT / UTC. – Arnoldas Bendoraitis Sep 09 '16 at 20:25
  • @ArnoldasBendoraitis *GMT is the same as UTC* Then why `[TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]::UtcNow,'UTC','GMT Standard Time')` and `[DateTime]::UtcNow` return different values? *does not support Daylight Saving Time* `[TimeZoneInfo]::FindSystemTimeZoneById('GMT Standard Time').SupportsDaylightSavingTime` print `True` for me. Did you actually try it? Or you know it will not work and can not be bothered trying? – user4003407 Sep 09 '16 at 20:33
  • @PSA "It seems (at least to me) that whoever was in charge of defining timezones in Microsoft has really muddied the waters even further here. " http://stackoverflow.com/a/3760223/4405933 – Jaqueline Vanek Sep 09 '16 at 23:31
  • :D http://stackoverflow.com/a/23096379/4405933 – Jaqueline Vanek Sep 09 '16 at 23:52
  • @JaquelineVanek BTW, if you to notify me, then do not use `@PSA`. – user4003407 Sep 10 '16 at 04:30

2 Answers2

1

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.

Arnoldas Bendoraitis
  • 1,055
  • 1
  • 11
  • 17
0

I noticed the incorrect assumption that GMT was British time this several years back (while working at Microsoft.) I think I filed a bug for it, but I'm not sure. It seems like you need a custom time zone.

I found this interesting post on defining custom time zones: http://subjectivecoder.blogspot.com.au/2013/04/creating-custom-windows-timezones.html. It should be possible to do this with PowerShell.

Burt_Harris
  • 6,415
  • 2
  • 29
  • 64