【问题标题】:TimeZoneInfo.ConvertTimeFromUtc is not correctly applying DST on a deployed Azure WebjobTimeZoneInfo.ConvertTimeFromUtc 未在已部署的 Azure Webjob 上正确应用 DST
【发布时间】:2019-09-07 19:17:43
【问题描述】:

我们有一个在 .Net Framework 4.7.1 上运行的网络作业,它执行从 DateTimeOffset.UtcNow 到智利大陆时间的日期时间转换(如果我没记错“太平洋标准时间”的话)。

在本地(在 Windows 10 机器上)运行此 Web 作业时,它可以正常工作并执行应用 DST 的转换,但是当部署到 Azure 应用服务时,它不再起作用,并且最终的 DateTime 总是在一小时后比现在的官方时间。

我最初从TimeZoneInfo.ConvertTimeBySystemTimeZoneId切换到TimeZoneInfo.ConvertTimeFromUtc的假设是第一个不考虑夏令时但没有用;

然后我尝试切换“错误”我自己的 PC,将我的时区更改为“UTC_dstoff”并在“调整日期/时间”菜单中禁用“自动调整夏令时”和“自动设置时间”选项' 但它在本地仍然可以正常工作;

我尝试的最后一件事是使用环境变量 WEBSITE_TIME_ZONE 将时区更改为 App Service 为“太平洋 SA 标准时间”,但这并不是决定性的。我会说它最初似乎有效,但在时区进行了更多更改后,它又开始增加一小时。

这可以用以下几行重现:

var timeZoneId = "Pacific SA Standard Time";
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var dateTimeOffset = DateTimeOffset.UtcNow;

var localTime = TimeZoneInfo.ConvertTimeFromUtc(dateTimeOffset.DateTime, timeZone);

我希望函数 TimeZoneInfo.ConvertTimeFromUtc 在本地和 Azure 应用服务中选择具有 DST 的时区时正确应用 DST。相反,它似乎在 Windows 10 中正常运行,但在 Azure 应用服务中随机运行。

【问题讨论】:

    标签: c# azure azure-webjobs dst .net-4.7.1


    【解决方案1】:

    更新

    似乎KB4486459 中涵盖Chile's DST schedule in 2019 更改的时区更新尚未应用于Azure 应用服务。从而解释了为什么在某些日期本地得到的结果与部署到 Azure 时不同。

    4486459 包含在 Azure March 2019 Guest OS patches 中,仍在部署到 Azure 应用服务。因此,此问题将在个别实例收到更新时自行解决。


    原答案

    一些事情:

    • WEBSITE_TIME_ZONE 仅应在您有无法更改且适​​用于本地时间的代码时使用。例如,如果您有很多呼叫DateTime.Now,这将反映本地时区。更改 WEBSITE_TIME_ZONE 将更改用于确定的时区。如果您可以控制自己的代码,那么永远不要写DateTime.Now,或使用任何其他依赖于本地时区的函数。那么您将永远不需要使用此设置。将其视为最后的手段 - 不是推荐的做事方式。

    • 一般来说,您应该尽量不要编写会根据系统时区设置改变其行为的服务器端代码,无论是本地计算机控制面板中的设置,还是 WEBSITE_TIME_ZONE 设置上面提到过。

    • 这并不重要,但“自动调整夏令时”设置几乎应该始终保持打开状态。禁用它(或通过将_dstoff 传递给TZUtil.exe)主要是旧设置。 (有一个罕见的边缘情况,但不值得在这里讨论。)

    • 是的,"Pacific SA Standard Time" 是智利大陆(圣地亚哥)的正确 Windows 时区 ID。其他适用于智利的是蓬塔阿雷纳斯 ("Magallanes Standard Time") 和复活节岛 ("Easter Island Standard Time")。

    • 请注意,智利 2019 年夏令时时间表的日期发生了变化。Read about it here。这是 Microsoft 在 2019 年 2 月的更新中发布的,described here。此更新应该已经安装在您的 Azure 网站上,但您可能需要验证您自己的本地计算机。

    • 您说您最初使用的是TimeZoneInfo.ConvertTimeBySystemTimeZoneId。如果您使用了接受DateTime 的重载,请注意如果.KindDateTimeKind.Unspecified,那么它将被视为本地时间。如果您没有更改WEBSITE_TIME_ZONE,则默认本地时间 UTC。但如果你这样做了,那会影响行为。

    • 另外请注意,当您请求 DateTimeOffset.DateTime 属性时,类型将始终为 DateTimeKind.Unspecified。尽管这不会影响您当前的代码,因为TimeZoneInfo.ConvertTimeFromUtc 将未指定的种类视为 UTC(因此名称中的“FromUTC”)。

    • 1234563那么DateTimeKind 就不会妨碍你了。

    最后,我要指出的是,您的问题对于什么不完全起作用并不是很清楚。您展示的代码最终会做正确的事情,即使它并不理想。无论您更改系统设置或WEBSITE_TIME_ZONE,它都不会产生间歇性结果。有没有可能你只是在不同的日期和时间喂食,看到有些有 DST 而有些没有?如果是这样,那可能是完全正常的。我会对照Chile DST schedule 检查它们是否对齐。请记住,这与您执行代码时是否应用 DST 无关,而是它是否适用于给定的值

    如果您仍然遇到问题,请提供输入和输出示例以及您的预期。谢谢。

    【讨论】:

    • 感谢@matt-johnson 简而言之,我的问题是,当我们使用 DateTimeOffset.UtcNow 捕获当前的 DateTime 时,它​​会返回正确的 UTC 时间(例如 '4/19/2019 9:28:20 AM +00:00')但是当我使用上述函数将其转换为智利当地时间时,它会在一小时后在 Azure 中返回(所以 '4/19/2019 6:28:20 AM' 当我期望它是' 2019 年 4 月 19 日上午 5 点 28 分 20 秒')。无论如何,你有一些我想检查的好点!
    • Azure 网站可能没有安装该更新。这可以解释你的发现。它在 5 月 5 日之后的日期是否正常工作?那将是旧时间表上的 DST 结束日期。
    • 如果您确实发现 Azure 缺少更新(它是 KB4486459),请通过门户打开支持请求。谢谢。
    • 感谢@matt-johnson,它似乎已经按预期工作了。我假设更新已经部署 - 超级快:)-
    • @Glezalex - 在顶部查看我的更新答案。在我们讨论时,您的实例可能已收到更新。 :)
    【解决方案2】:

    在Azure上,将WEBSITE_TIME_ZONE添加到Pacific SA Standard Time,使用TimeZoneInfo结构的方法如下:

    DateTime timeUtc = DateTime.UtcNow;
    TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific SA Standard Time"); 
    DateTime kstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, timeZone );
    

    【讨论】:

    • 这与问题中的内容没有太大区别。这没有错,只是没有多大帮助。唯一真正的区别是timeUtc.Kind 将是DateTimeKind.Utc 而不是DateTimeKind.Unspecified,但TimeZoneInfo.ConvertTimeFromUtc 的行为方式与两者相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多