【问题标题】:PowerShell - Converting UTC To British Summer TimePowerShell - 将 UTC 转换为英国夏令时
【发布时间】:2016-09-09 16:15:10
【问题描述】:

我编写了一个简单的函数来将任何 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)传递给转换函数时,它无法识别夏令时,因此返回一小时后的英国时间值(我试图通过使用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 类型?

任何解释都将不胜感激。

【问题讨论】:

  • [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($UTCTime,'UTC','GMT Standard Time')
  • @PSA,GMT 不是“英国”时间
  • @JaquelineVanek 你这里没有伦敦[TimeZoneInfo]::FindSystemTimeZoneById('GMT Standard Time').DisplayName吗?伦敦不再是英国了吗?
  • @PetSerAl,Jaqueline 是对的,GMT 与“英国时区”并不完全相同。 GMT 与 UTC 相同(我不需要转换它),它不支持从 3 月的最后一个星期日到 10 月的最后一个星期日引入夏令时,即这次是 BST(英国夏令时)比格林威治标准时间/世界标准时间早 1 小时。
  • @ArnoldasBendoraitis GMT 与 UTC 相同 那么为什么 [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]::UtcNow,'UTC','GMT Standard Time')[DateTime]::UtcNow 返回不同的值? 不支持夏令时 [TimeZoneInfo]::FindSystemTimeZoneById('GMT Standard Time').SupportsDaylightSavingTime print True 为我。你真的试过了吗?或者你知道它不会起作用,也懒得去尝试?

标签: powershell datetime utc datetime-conversion


【解决方案1】:

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

首先,感谢@PetSerAl 建议使用微软定义的“GMT 标准时间”时区,我和社区中的其他用户发现该时区的命名存在争议,因为实际 GMT 在现实生活中有不同的偏移量(因此造成了混乱)但是,我发现它正是我需要在我的情况下使用的。

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-09-16
      • 2014-06-01
      • 2019-09-29
      • 2017-09-10
      • 2016-06-14
      • 1970-01-01
      • 2012-05-01
      • 2018-07-06
      • 1970-01-01
      相关资源
      最近更新 更多