gpt4 book ai didi

angularjs - 从 Angular (时区)到服务器(UTC)然后UTC到时区的日期

转载 作者:行者123 更新时间:2023-12-03 08:13:37 25 4
gpt4 key购买 nike

我在将日期恢复到正确的时区时遇到问题。

首先在本地机器上,一切正常,但在服务器中却没有:服务器托管在美国,而客户端大多在澳大利亚。

所以日期从 angular app("12/23/2015 11:00:00 AM") 发送到服务器,服务器将日期作为 utc 存储在数据库中,直到此时一切正常(我检查了日期存储在正确的UTC中)

book.StartDateTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.SpecifyKind(book.StartDateTime.Value, DateTimeKind.Unspecified), ToolsHelper.OlsonTimeZoneToTimeZoneInfo(locationDetails.TimeZone)); // book.CreatedDate.Value.ToUniversalTime();

问题是:

当客户端请求一些日期存储在数据库中时。存储在数据库中的日期像这样返回给客户端:
 bookview.StartDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.SpecifyKind(bookli.StartDateTime.Value, DateTimeKind.Utc), ToolsHelper.OlsonTimeZoneToTimeZoneInfo(deCompany.TimeZone));

我检查了一下,此时日期是“12/23/2015 11:00:00 AM”->转换在服务器中正确(在服务器端我放了一个日志),

但在 Angular 显示为“12/23/2015 10:00:00 PM”

所以显然问题是日期何时由 api 传输到客户端,也许何时转换为 JSON

我尝试了不同的方法,但没有任何效果,我删除了“DateTime.SpecifyKind”,我将日期转换为字符串,然后再转换回日期时间格式,但似乎没有任何效果。

我能做什么?

最佳答案

一些东西:

  • 你的例子不完整,所以我只能推测一些领域。最好同时显示双方,包括如何在 Angular 中加载和解析数据,以及数据在网络上的样子。
  • 您不应该以特定于语言环境的格式来回发送日期,例如 "12/23/2015 11:00:00 AM" .您可以在 UI 中使用它们,但它们不适合通过网络(在您的 JSON 中)。相反,您应该使用 ISO8601/RFC3339 ,例如 "2015-12-23T11:00:00Z" . (如果您正在使用 WebAPI,您可能已经在这样做了。)
  • 一个 DateTime序列化为 ISO8601 格式时的对象与相关联的 DateTimeKind 耦合在 Kind属性(property)。
  • 如果KindUtc ,那么 ISO8601 字符串将以 Z 结尾.
  • 如果KindLocal ,那么 ISO8601 字符串将以该时间戳的机器本地偏移量结束,例如 -08:00 .
  • 如果KindUnspecified ,那么 ISO8601 字符串将没有 Z或偏移 - 这意味着它不能明确表示特定时刻。

  • 这最终是导致错误的原因。您正在转换 DateTime到另一个时区,留下 Unspecified kind,然后在没有偏移的情况下进行序列化 - 因此在客户端(可能)在浏览器的本地时区中进行解释。
  • 更好的方法是使用 DateTimeOffset而不是 DateTime .那你就不用担心Kind ,并且偏移量始终存在。如果您更改您的 bookview.StartDateTimeDateTimeOffset键入,您可以执行以下操作来解决问题:
      DateTimeOffset dto = new DateTimeOffset(bookli.StartDateTime.Value, TimeSpan.Zero);
    bookView.StartDTO = TimeZoneInfo.ConvertTime(dto, ToolsHelper.OlsonTimeZoneToTimeZoneInfo(deCompany.TimeZone));
    这将确保偏移量保留在数据中。
  • 在客户端,请仔细注意 ISO 字符串的解析方式。如果它被加载到 Date对象,那么它确实会转换为客户端的时区。相反,您可以查看 moment.js用于客户端时间格式化。特别是使用 moment.parseZone将值保持在与它呈现的相同的偏移量中。例如:
      var s = moment.parseZone("2015-12-31T11:00:00+00:00").format("L LT"); // "12/31/2015 11:00 AM"
  • 在注释代码中,您还显示了对 DateTime.ToUniversalTime 的调用。 - 对此要非常小心。如果源种类是 Unspecified ,它被视为 Local .因此,计算机的本地时区反射(reflect)在转换后的值中。最好避免ToUniversalTimeToLocalTime完全。仅使用 TimeZoneInfo 上的转换方法.
  • ToolsHelper.OlsonTimeZoneToTimeZoneInfo也不是我们所知道的。但我假设它执行类似于 this one 的 CLDR 映射。 .但是,如果您无论如何都使用奥尔森时区,更好的方法是不使用 TimeZoneInfo根本。相反,使用 Noda Time ,具有对 tzdb 时区的 native 支持。
  • 关于angularjs - 从 Angular (时区)到服务器(UTC)然后UTC到时区的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34417666/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com