忽略时区偏移量转换日期 - JavaScript

4

我有一个返回日期的WCF REST服务,其格式如下:

/Date(1401993000000+0530)/

服务器上的日期值为:
6/6/2014 12:00:00 AM

我想在我的javascript代码中以UTC值解析它。

我尝试手动删除“+0530”字符串并将其解析为日期,但它会显示“无效日期”。

我还尝试根据这篇文章添加时区偏移量,但它给出了错误的值。

我该如何解析它?


3
这个应该不会出现“Invalid Date”的错误:new Date(1401993000000) - Lennholm
请提供一个 "最小化、完整性的可运行示例"(MCVE)。重点在于"可验证性"。 - evolutionxbox
@MikaelLennholm——是的,但是OP需要应用偏移量+0530。 - RobG
2个回答

2
这种格式通常被称为“ASP.NET JSON日期” - 因为它最初出现在ASP.NET和其他.NET的JavaScriptSerializerDataContractJsonSerializer类中。然而,它受到了严厉批评,最终被弃用,取而代之的是标准的ISO 8601格式,它是大多数现代.NET代码中使用的Json.Net库的默认格式。你仍然会在WCF和旧版的ASP.NET MVC中看到它。
该格式有两个主要变体:
  • /Date(1401993000000)/ - 仅时间戳
  • /Date(1401993000000+0530)/ - 带偏移量的时间戳
有时你会看到斜杠被反斜杠转义,例如\/Date(1401993000000)\/,这取决于它是如何生成的。解析器应该能够容忍这种情况,但不应该依赖它。
在显示的两种格式中,时间戳部分旨在表示自 Unix 纪元以来的毫秒数,即 1970 年 1 月 1 日 00:00:00.000 UTC。
我说“旨在”,因为在 .NET 中可能存在一个具有 DateTimeKind.UnspecifiedDateTime,它不可能映射回 UTC。在这种情况下,序列化程序将像具有 DateTimeKind.Local 一样运行。然后输出将反映计算机所在时区中调整为 UTC 的值,以及该时刻计算机的 UTC 偏移量。理想情况下,您不应该依赖此行为,因为来自不同时区的计算机会得到不同的结果。
当输出字符串中存在偏移量时,它的格式为+HHmm/-HHmm,其中正值位于格林威治标准时间以东 - 与ISO 8601标准相同的方向。然而,与ISO 8601不同的是,该值部分不会根据该偏移量进行调整。它仍然是基于UTC的。
换句话说:
  • /Date(1401993000000)/ = 2014-06-05T18:30:00Z
  • /Date(1401993000000+0530)/ = 2014-06-05T18:30:00Z + +0530 = 2014-06-06T00:00:00+05:30
由于这个原因,在使用此值创建JavaScript Date对象时,偏移量部分是多余的 - 因为Date对象将一个基于UTC的时间戳包装起来,并且没有保留提供的偏移量的规定。
你可以将字符串拆分为其各个部分并自行使用,但是考虑使用Moment.js来解析此字符串。它本身就能理解这种格式,并且可以返回一个对象,该对象保留了偏移量的信息。
var m = moment.parseZone("/Date(1401993000000+0530)/");

m.format() // "2014-06-06T00:00:00+05:30"

如果您正在寻找一个“Date”对象,您可以调用“m.toDate()”。生成的“Date”对象将具有相同的UTC时间戳,但由于“Date”对象的工作方式,任何本地时间函数只会使用主机环境的偏移量。
换句话说,在“Date”对象的输出中,“+0530”部分变得无用。您可能已经解析了“/Date(1401993000000)/”。

请问您能解释一下这是如何工作的吗?原帖中说:“6/6/2014 12:00:00 AM at the server”但并没有说明这是哪个时区的时间,您假设它也是+0530吗? - RobG
@RobG - 我扩展了我的答案。如果我漏掉了什么,请告诉我 :) - Matt Johnson-Pint
哈!又被诵读障碍折磨了一次!谢谢,问题已修复。 - Matt Johnson-Pint

0
你可以使用 Moment JS,这是在 JavaScript 中处理日期时间的更好方法之一。有很多函数可供使用。

https://momentjs.com/timezone/

查看已编辑的消息,不使用momentjs:

 var data = [ {"id":1,"start":"/Date(1401993000000+0530)/"} ];
  var myDate = new Date(data[0].start.match(/\d+/)[0] * 1);
  myDate =  new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60 * 1000);
  alert(myDate);


1
虽然我同意,但这并不是一个真正的答案,只是一条评论。我建议给OP一个momentjs解决他们问题的快速示例。 - evolutionxbox
1
这会得到错误的结果。它会调整为主机时区偏移量,而应该调整为提供的偏移量(即+0530); - RobG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接