PowerShell - 将 UTC 转换为英国夏令时

PowerShell - Converting UTC To British Summer Time

我写了一个简单的函数来将任何 UTC 时间转换为当前英国时间(取决于当前季节是否应用夏令时,结果是相同的 UTC 或 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
}

我也在不同的函数中使用它来获取当前的英国时间,它工作得很好:

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

    return $UKTime.ToString($Format)
}

但是,当我尝试将文件创建时间(当然是 UTC 时间)传递给转换函数时,它无法识别夏令时,因此 returns 英国时间值落后一小时(我尝试使用 Get-Date 通过完全相同的时间 - 没有问题):

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

我找到了帮助我按预期工作的修复程序(通过在作为参数传递之前将 DateTime 类型转换为 String):

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

但是,我不太确定为什么会这样。将此与 Get-Date 一起使用与将文件创建时间作为参数传递之间有什么区别,因为它们都具有相同的 DateTime 类型?

任何解释将不胜感激。

几年前(在 Microsoft 工作时)我注意到错误的假设 GMT 是英国时间。我想我为此提交了一个错误,但我不确定。看来您需要一个自定义时区。

我发现这个关于定义自定义时区的有趣 post:http://subjectivecoder.blogspot.com.au/2013/04/creating-custom-windows-timezones.html。使用 PowerShell 应该可以做到这一点。

经过广泛的测试和与同行的讨论,我想我现在已经找到了我原来问题的答案。

首先,感谢@PetSerAl 建议使用 Microsoft 定义的 'GMT Standard Time' 时区,我和社区中的其他用户发现这个命名有争议,请记住实际 GMT 在现实生活中(因此混乱),然而,我发现它正是我需要在我的案例中使用的东西。

那么为什么在 UTC 中同时传递字符串和 DateTime 对象时得到不同的结果?答案是这样的:

一旦我将对象传递给函数(这是从 UTC 文件创建时间戳中获取时间的结果),它就会自动启动为正确的 UTC 时间类型对象,具有 属性 .Kind 设置为值 UTC(此 属性 只有两个有效值 - UTCLocal 其他所有值)。获取此参数的函数最初识别的是 UTC 类型时间,它无法检测到夏令时,因为 UTC 时区根本不支持它。 在将字符串发送到函数的第二种情况下,这里的主要区别在于,一旦将实际字符串转换为函数内的 DateTime 对象,它就使用了 Get-Date,默认情况下,它使用 Get-Date 实例化结果对象本地机器的时间(我在立陶宛工作)因此 IsDaylightSavingTime() 现在可以 return $True 值,因为我的本地时区确实支持它。