【问题标题】:Microsoft Azure Webjobs timezone differenceMicrosoft Azure Webjobs 时区差异
【发布时间】:2019-07-03 13:46:35
【问题描述】:

当传递了实体上的给定时间戳时,我有几个 Azure WebJobs 应该从 DB 中获取一些实体。问题是我的时区(格林威治标准时间 + 1 - 丹麦),截至目前(夏令时)有 2 小时的差异。 因此,WebJobs 当前获取 2 小时为时已晚。 在服务中,我使用DateTime.Now 作为当前时间的标记。 数据库中的时间戳看起来不错。 我需要弄清楚如何使它们同步,最好不必将整个服务重写为DateTime.UtcNow

我在 Azure 中添加了WEBSITE_TIME_ZONE 应用程序设置,并将其设置为Romance Standard Time,这应该是正确的,应该根据其他帖子解决问题,但这没有帮助。

Microsoft Azure,Webjob, in which timezone a webjob runs if I schedule a webjob to run daily at specified time using cron expression

来自服务的 C# 代码 sn-p:

var now = DateTime.Now;

var orderBatch = await db.OrderEntities
  .Where(o => o.OrderStatus == (int)Status.Accepted)
  .Where(o => o.ExecutionTime.HasValue && o.ExecutionTime < now)
  .Where(o => (o.NextSendTry == null || o.NextSendTry < now))
  .Select(o => new
  {
    OrderId = o.Id
  })
  .Take(100)
  .ToListAsync();

从当前时间为 04:38 而不是 02:38 的 WebJobs 日志记录 sn-p。 有一个订单的执行时间到 03:00,所以它应该已经被提取,但直到 05:00:

[06/29/2019 02:38:21 > 98c279: INFO] 2019-06-29 04:38:21.618 +02:00 
[INF] 0 orders fetched from db @ 6/29/2019 4:38:21 AM

Web 应用程序应具有Romance Standard Time,并且在此应用程序服务中运行的 WebJobs 应具有相同的时区。 因此DateTime.Now 应该是服务器(Azure Web 应用)当前时间。

----- 更新 -----

根据 Matt 的 cmets,我们尝试在服务中使用 UTC 时间,方法是使用 .toUniversalTime() 扩展名在运行时转换我们的 DB 时间,然后再次检查 DateTime.UtcNow。 它工作正常,DB 中的时间仍然是我们希望的当地时间。

【问题讨论】:

  • 嗨。乐于助人,但缺少很多细节。你能告诉我们ExecutionTypeNextSendTry的数据类型是什么吗?数据库中对应的类型呢?我假设这是 Azure SQL DB?或者是别的什么?数据库中的值是否也是丹麦当地时间?还是他们在UTC?谢谢。
  • 另外,您是否有充分的理由不能编写服务来使用 UTC 时间?这是一个更好的做法。即使你得到这个工作,在 DST 回退过渡期间你也会有潜在的错误。在您的情况下,当订购时间或“现在”为2019-10-27 02:00 时,您的代码将不知道这是第一个实例 (UTC+2) 还是第二个实例 (UTC+1)。我通常会告诉人们尽量不要依赖WEBSITE_TIME_ZONE。它在大多数情况下确实有效,但它是一个拐杖。仅在绝对必要时依靠它。
  • 嗨@MattJohnson。感谢回复! ExecutionTime 和 NextSendTry 都是 DateTime 类型。它们作为日期时间存储在数据库中。该数据库是一个 Azure SQL 数据库。是的,这些值对应于本地时区的值。在我们的后端系统中,我们不将时间存储为 UTC,这也是我们不使用 UTC 在服务中检查的原因。使用 UTC 可能会对我们的代码库产生重大影响。这就是寻找不同解决方案的原因。在 Azure 之外,这从来都不是问题。

标签: azure datetime timezone azure-webjobs


【解决方案1】:

我建议使用DateTimeOffset(.NET)/datetimeoffset(SQL) 数据类型,而不是将时间戳作为DateTime(.NET)/datetime2(SQL) 存储在您的数据库中。

然后您可以在 OrderEntity 属性中设置 ExecutionTime 为 DateTimeOffset.Nownew DateTimeOffset(DateTime specificTime) 并对您的 webjob 代码执行相同的操作。

比较将考虑时区之间的时移。

希望对您有所帮助。干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2015-04-02
    • 1970-01-01
    相关资源
    最近更新 更多