我正在使用Bing Routes API,并且它以这种格式返回日期:
/Date(1538245980000-0700)/
它看起来像Unix时间戳(以毫秒为单位),后跟一个时区。 Moment文档claim to be able to handle these correctly,但他们也say that
Unix时间戳和Date对象引用特定的时间点,因此在构造时使用时区偏移是没有意义的。
根据其他情况(星期六星期六早上是从公共汽车离开Stawell的时间,距离墨尔本几小时),我非常确定上述时间应该是澳大利亚/墨尔本AEST的上午11:33(+10: 00)。
但是使用moment.timezone:
console.log(moment.parseZone('/Date(1538245980000-0700)/').format('h:mma Z'));
"11:33am -07:00"
这似乎真的是错误的:这是指某个时刻:
Bing错误吗?为什么要包含此时区?
还是我使用Moment错误?在这种情况下,用本地时区将这种格式转换为正确时间的正确方法是什么?
答案 0 :(得分:2)
这是JavaScriptSerializer
类(和其他类)产生的过时的“ ASP.NET JSON Date Format”。斯科特·汉塞尔曼(Scott Hanselman)以及其他人也对此做了a blog post back in 2012。 (通常,现代系统应改用ISO 8601 / RFC 3339格式。)
ASP.NET JSON日期格式包含两个部分:
第一部分始终是Unix时间戳(以毫秒为单位)。换句话说,自1970-01-01 00:00:00.000 UTC以来经过的毫秒数,未考虑leap秒。它不会针对时区进行调整-始终基于UTC 。
第二部分是可选的,并且经常被省略。当存在时,它反映出时域偏移量,应该对接收者有意义。但是,它通常是通过在.NET中将DateTime
属性为.Kind
的{{1}}序列化生成的,在这种情况下,它将根据反映该日期的时区偏移量。服务器的本地时区。通常,该时区是不可挽回的。请注意,与ISO 8601不同,对基值进行了 not 调整,以反映此偏移量。 换句话说,偏移量是多余的。
因此,您提供的时间戳确实代表您列出的值。 (不过请注意,墨尔本目前是UTC + 10,而不是UTC + 11。)
关于Moment,请记住DateTimeKind.Local
旨在将矩对象的时区偏移设置为输入中提供的偏移(在这种情况下为parseZone
)。如果您不关心该偏移量,则可以使用任何其他解析函数:
-0700
在以上所有示例中,仅在第一个示例中使用了moment.parseZone('/Date(1538245980000-0700)/').format()
//=> "2018-09-29T11:33:00-07:00" (always)
moment('/Date(1538245980000-0700)/').format()
//=> "2018-09-29T14:33:00-04:00" (example based on the local time zone being US Eastern time)
moment.utc('/Date(1538245980000-0700)/').format()
//-> "2018-09-29T18:33:00Z" (always, since parsing as UTC)
moment.tz('/Date(1538245980000-0700)/', 'Australia/Melbourne').format()
//=> "2018-09-30T04:33:00+10:00" (always - since time zone provided)
。
所以-如果您希望该值代表墨尔本的时间,那么是-Bing错误。数据可能还有其他设置或方面需要考虑。也许这是一个错误,如果是这样,您应该这样报告。
如果是这样,并且您需要补偿,则请执行以下操作:
-0700