为什么 outlook.timezones.converttime 的 DST 更改错误?

Why does outlook.timezones.converttime get the DST change wrong?

我在 Excel 中使用以下 VBA 代码:

Function tzAtotzB(srcDT As Date, srcTZ As String, dstTZ As String) As Date
    Dim OutlookApp As Object
    Dim TZones As TimeZones
    Dim convertedTime As Date
    Dim sourceTZ As TimeZone
    Dim destTZ As TimeZone
    Dim secNum As Integer
    
    Set OutlookApp = CreateObject("Outlook.Application")
    Set TZones = OutlookApp.TimeZones
    Set destTZ = TZones.Item(dstTZ)
    Set sourceTZ = TZones.Item(srcTZ)
    
    tzAtotzB = TZones.ConvertTime(srcDT, sourceTZ, destTZ)

End Function

Function CETtoUTC(srcDT As Date) As Date
    CETtoUTC = tzAtotzB(srcDT, "Central Europe Standard Time", "UTC")
End Function

Function UTCtoCET(srcDT As Date) As Date
    UTCtoCET = tzAtotzB(srcDT, "UTC", "Central Europe Standard Time")
End Function

由于某种原因,结果不是人们所期望的:

Debug.Print UTCtoCET("26/03/2022 23:00:00")
27/03/2022
Debug.Print UTCtoCET("27/03/2022 00:00:00")
27/03/2022 02:00:00 
Debug.Print CETtoUTC("27/03/2022 02:00:00")
27/03/2022 
Debug.Print UTCtoCET("28/03/2021 00:00:00")
28/03/2021 02:00:00 

CET 应该在 3 月的最后一个星期日 (source) 01:00 UTC 开始从 UTC+1 切换到 UTC+2,但上面的输出显示从 UTC+ 切换1 到 00:00 UTC 的 UTC+2,这显然是不正确的。

我没有发现我的代码有任何问题。这是 Microsoft 代码库中的已知错误吗?

这似乎是 Outlook VBA 对象模型中 TimeZones.ConvertTime 方法的底层实现中的错误。

使用您问题中的代码,在引用“Microsoft Outlook 16.0 对象库”后,我能够在 VBA 中重现不准确的结果。 OutlookApplication.Version16.0.0.14931.

正确 结果在同一台 Windows 机器上的 .NET 应用程序 运行 中使用 .NET [=15] 上的转换方法获得=] 对象。据我所知,它使用 Windows 注册表中的时区数据,这与 Outlook VBA 库使用的数据相同。

下面是演示正确结果的 .NET C# 代码:

var zone = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");

var input1 = DateTimeOffset.Parse("2022-03-27T00:00:00Z");
var output1 = TimeZoneInfo.ConvertTime(input1, zone);
Console.WriteLine($"{input1.UtcDateTime:yyyy-MM-dd'T'HH:mm:ssK} => {output1:yyyy-MM-dd'T'HH:mm:sszzz}");

var input2 = DateTimeOffset.Parse("2022-03-27T01:00:00Z");
var output2 = TimeZoneInfo.ConvertTime(input2, zone);
Console.WriteLine($"{input2.UtcDateTime:yyyy-MM-dd'T'HH:mm:ssK} => {output2:yyyy-MM-dd'T'HH:mm:sszzz}");

输出:

2022-03-27T00:00:00Z => 2022-03-27T01:00:00+01:00
2022-03-27T01:00:00Z => 2022-03-27T03:00:00+02:00

这显示了正确的转换,因此数据是正确的。因此,问题必须特定于 Outlook VBA 实施。如果这对您很重要,我建议 opening a support issue with Microsoft。你可以参考这个答案。