TimeZoneInfo.ConvertTimeFromUtc未在部署的Azure Webjob上正确应用DST

问题描述 投票:2回答:2

我们有一个在.Net Framework 4.7.1上运行的webjob,它执行从DateTimeOffset.UtcNow到智利大陆时间的日期时间转换(即如果我没有误解为“Pacific SA标准时间”)。

在本地运行此webjob(在Windows 10计算机中)时,它可以正常工作并执行应用DST的转换,但是当部署到Azure应用服务时,这不再起作用,并且最终的DateTime总是比当前晚一个小时官方时间。

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

然后我尝试切换“错误”我自己的电脑,将我的时区更改为'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);

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

c# azure azure-webjobs dst .net-4.7.1
2个回答
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,或使用任何其他依赖于本地时区的函数。然后,您将永远不需要使用此设置。认为这是最后的手段 - 不是推荐的做事方式。
  • 通常,您应该尝试不编写将根据系统时区设置更改其行为的服务器端代码,无论是本地计算机控制面板中的设置,还是上面提到的WEBSITE_TIME_ZONE设置。
  • 并不是它应该重要,但几乎总是保持“自动调整夏令时”设置。禁用它(或通过将_dstoff传递给TZUtil.exe)主要是遗留设置。 (有一个罕见的边缘情况,但在这里不值得讨论。)
  • 是的,"Pacific SA Standard Time"是智利大陆(Santiago)的正确Windows时区ID。其他适用于智利的是蓬塔阿雷纳斯("Magallanes Standard Time")和复活节岛("Easter Island Standard Time")。
  • 请注意,2019年智利的夏令时日期有所变化.Read about it here。微软于2019年2月更新了described here。此更新应已安装在Azure网站上,但您可能需要验证自己的本地计算机。
  • 你说你最初使用的是TimeZoneInfo.ConvertTimeBySystemTimeZoneId。如果你使用了接受DateTime的重载,那么请注意,如果.KindDateTimeKind.Unspecified,那么它将被视为当地时间。如果您未更改WEBSITE_TIME_ZONE,则默认本地时间为UTC。但如果你这样做,那将影响行为。
  • 另外请注意,当你要求.DateTimeDateTimeOffset属性时,那种将永远是DateTimeKind.Unspecified。虽然这不会影响您当前的代码,因为TimeZoneInfo.ConvertTimeFromUtc将未指定的类型视为UTC(因此名称中为“FromUTC”)。
  • 如果你正在使用DateTimeOffset类型,你最好使用TimeZoneInfo.ConvertTimeBySystemTimeZoneIdTimeZoneInfo.ConvertTime,重载接受并返回DateTimeOffset。那么DateTimeKind不会妨碍你。

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

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


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 );
© www.soinside.com 2019 - 2024. All rights reserved.