为什么 Outlook.timezones.converttime 的 DST 更改错误?
我在 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 应该从 UTC+1 切换到 UTC+2,从 3 月最后一个星期日的 01:00 UTC 开始(source),但上面的输出显示在 00:00 UTC 从 UTC+1 切换到 UTC+2,这显然是不正确的。
我没有发现我的代码有什么问题。这是 Microsoft 代码库中的已知错误吗?
I am using the following VBA code in Excel:
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
For some reason the results are not what one would expect:
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 is supposed to switch from UTC+1 to UTC+2 starting at 01:00 UTC on the last Sunday of March (source), but the output above shows a switch from UTC+1 to UTC+2 at 00:00 UTC, which is plain incorrect.
I don't see anything wrong with my code. Is this a known bug within Microsoft's codebase?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

这似乎是
TimeZones 底层实现中的错误Outlook VBA 对象模型中的 .ConvertTime
方法。使用您问题中的代码,在引用“Microsoft Outlook 16.0 对象库”后,我能够在 VBA 中重现不准确的结果。
OutlookApplication.Version
为16.0.0.14931
。使用 .NET
TimeZoneInfo
对象上的转换方法,在同一 Windows 计算机上运行的 .NET 应用程序中会得到正确的结果。据我所知,它使用 Windows 注册表中的时区数据,这与 Outlook VBA 库使用的数据相同。下面是演示正确结果的 .NET C# 代码:
哪个输出:
显示了正确的转换,因此数据是正确的。因此,该问题必须特定于 Outlook VBA 实现。如果这对您很重要,我建议向 Microsoft 提出支持问题 。你可以参考这个答案。
This appears to be a bug in the underlying implementation of the
TimeZones.ConvertTime
method in the Outlook VBA Object Model.Using the code in your question, I was able to reproduce the inaccurate results in VBA after referencing the "Microsoft Outlook 16.0 Object Library". The
OutlookApplication.Version
is16.0.0.14931
.The correct results come through in a .NET application running on the same Windows machine using the conversion methods on the .NET
TimeZoneInfo
object. That uses the time zone data from the Windows Registry, which is the same data that the Outlook VBA library uses, as far as I know.Here's the .NET C# code that demonstrates the correct results:
Which outputs:
That shows the correct transition, so the data is correct. Thus the problem must be specific to the Outlook VBA implementation. I suggest opening a support issue with Microsoft if this is important to you. You can reference this answer.