TimeZoneInfo.ConvertTimeFromUtc没有在已部署的Azure Webjob上正确应用DST

时间:2019-04-17 13:59:50

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

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

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

我最初是从TimeZoneInfo.ConvertTimeBySystemTimeZoneId切换到TimeZoneInfo.ConvertTimeFromUtc的,前提是第一个不考虑DST但却不起作用;

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

我最后尝试尝试的是使用环境变量WEBSITE_TIME_ZONE将时区更改为App Service,并将其更改为“ Pacific SA Standard Time”,但这并不是唯一的。我会说它最初似乎有效,但是在更改时区后又开始增加一小时。

可以用以下几行来复制:

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

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

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

2 个答案:

答案 0 :(得分:1)

在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 );

答案 1 :(得分:1)

更新

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

4486459包含在Azure March 2019 Guest OS patches中,并且仍在部署到Azure App Service中。因此,当单个实例接收更新时,此问题将自行解决。


原始答案

几件事:

  • WEBSITE_TIME_ZONE仅在具有无法更改且适​​用于当地时间的代码时才使用。例如,如果您有许多对DateTime.Now的呼叫,则将反映本地时区。更改WEBSITE_TIME_ZONE将更改用于确定时间的时区。如果您可以控制自己的代码,则永远不要编写DateTime.Now或使用任何其他依赖于本地时区的函数。然后,您将不需要使用此设置。认为这是不得已的做法-并非推荐的做事方式。

  • 通常,您应该尝试不要编写会根据系统时区设置而改变其行为的服务器端代码,无论是本地计算机上控制面板中的代码还是{{1} }设置。

  • 这无关紧要,但是“自动调整夏令时”设置应该几乎始终保持打开状态。禁用它(或通过将WEBSITE_TIME_ZONE传递到_dstoff)通常是一个旧设置。 (有一种罕见的情况,但在这里不值得讨论。)

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

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

  • 您说您最初使用"Easter Island Standard Time"。如果您使用了接受TimeZoneInfo.ConvertTimeBySystemTimeZoneId的重载,那么请注意,如果DateTime.Kind,那么它将被视为本地时间。如果您未更改DateTimeKind.Unspecified,则默认本地时间 UTC。但是,如果这样做,那将影响行为。

  • 还请注意,当您要求WEBSITE_TIME_ZONE的{​​{1}}属性时,种类将始终为.DateTime。尽管这不会影响您当前的代码,因为DateTimeOffset会将未指定的类型视为UTC(因此名称中使用了“ FromUTC”)。

  • 如果您使用的是DateTimeKind.Unspecified类型,最好使用TimeZoneInfo.ConvertTimeFromUtc或仅使用DateTimeOffset,因为接受并返回TimeZoneInfo.ConvertTimeBySystemTimeZoneId的重载。这样TimeZoneInfo.ConvertTime不会妨碍您。

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

如果仍然遇到问题,请用输入和输出示例以及您的预期进行评论。谢谢。