加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – 从角度(时区)到服务器(utc)的日期,然后是utc到Time

发布时间:2020-12-17 17:15:37 所属栏目:安全 来源:网络整理
导读:我有一个问题,在正确的时区恢复日期. 在本地机器上一切都很冷,一切正常,但不在服务器中:服务器托管在美国,客户大多在澳大利亚. 所以从角度应用程序(“12/23/2015 11:00:00 AM”)发送日期到服务器,服务器在数据库中存储日期为utc,直到这一切一切正常(我检查
我有一个问题,在正确的时区恢复日期.

在本地机器上一切都很冷,一切正常,但不在服务器中:服务器托管在美国,客户大多在澳大利亚.

所以从角度应用程序(“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” – >转换是在服务器中(在服务器端我放了一个日志),

但在角度显示为“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,则可能已经在执行此操作.)
>序列化为ISO8601格式的DateTime对象与Kind属性中的关联DateTimeKind耦合.

>如果Kind是Utc,则ISO8601字符串将以Z结尾.
>如果Kind是Local,则ISO8601字符串将以该时间戳的机器本地偏移量结束,例如-08:00.
>如果Kind未指定,则ISO8601字符串将不具有Z或偏移 – 这意味着它无法明确地表示特定时刻.

这最终是导致错误的原因.您正在将DateTime转换为另一个时区,这使得它具有Unspecified种类,然后在没有偏移的情况下进行序列化 – 因此在客户端上(可能)在浏览器的本地时区进行解释.
>更好的方法是使用DateTimeOffset而不是DateTime.然后您不必担心Kind,并且始终存在偏移量.如果将bookview.StartDateTime更改为DateTimeOffset类型,则可以执行以下操作来解决问题:

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.因此,计算机的本地时区将反映在转换后的值中.最好完全避免ToUniversalTime和ToLocalTime.仅使用TimeZoneInfo上的转换方法.
> ToolsHelper.OlsonTimeZoneToTimeZoneInfo也不是我们所知道的.但是我会假设它执行类似于this one的CLDR映射.但是,如果你正在使用Olson时区,那么更好的方法是根本不使用TimeZoneInfo.相反,使用Noda Time,它具有对tzdb时区的本机支持.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读