moment.js从现在开始在firefox /即chrome中报告不同的结果

时间:2013-10-01 00:29:37

标签: momentjs

我们愚蠢地假设一块momentjs代码可以在所有浏览器中使用。现在它正确地在chrome中工作,但是所有其他浏览器都没有应用UTC偏移。如何让这个code在其他浏览器中保持一致?现在chrome正在运行,其他所有都没有。

 new moment(new Date(date)).fromNow();
 //below shows an example of an exact date. 
 var now = new moment(new Date("2013-09-30T23:33:36.937")).fromNow();

在Chrome中,您会看到类似“现在”的内容,您会在“4小时内”看到所有其他浏览器

3 个答案:

答案 0 :(得分:7)

让它发挥作用的方法:

var now = moment.utc("2013-10-01T13:15:30.937").fromNow();

请注意,如果您将其变为“日期”并致电moment.utc

var now = moment.utc(new Date("2013-10-01T13:15:30.937")).fromNow();

它无效。现在我想到它是有道理的。

答案 1 :(得分:5)

原始答案

试试这个:

var now = moment(date).fromNow();

但是rutter是正确的,您应该指定Z或像-07:00这样的偏移量。在.net中,您应该确保使用设置为Utc的DateTime .Kind或使用DateTimeOffset字段。

扩展答案

您应该了解,当您发送2013-10-01T13:15:30.937字符串时,您不会发送任何上下文。无论时间是在UTC,服务器的时区,还是在浏览器的时区,都无法从该字符串中知道。

如果您将其直接传递给moment("2013-10-01T13:15:30.937"),它将假设浏览器的本地时区的上下文。

正如您所发现的,您可以使用.utc函数明确告知此时间是UTC时间,例如moment.utc("2013-10-01T13:15:30.937")

虽然这将工作,但有充分的理由不依靠它。例如,如果您将相同的服务器API用于其他应用程序,或者可能为第三方使用,该怎么办?除非你单独告诉他们时间戳是代表UTC的,否则无法知道。

这些字符串采用ISO 8601 / RFC 3339格式。该规范的一部分描述了如何指示时间戳是UTC。您只需在末尾添加Z即可。如果您提供Z,则此时间戳的任何使用者都将知道该时间应解释为UTC。当然,如果你直接将它传递给时间,例如moment("2013-10-01T13:15:30.937Z"),它将给出你期望的结果。

您在评论中说,您是从ASP.Net Web API生成这些值的。在调试模式下运行应用程序并设置断点,以便检查控制器的输出。当您查看相关的特定DateTime属性时,您会看到它有自己的.Kind属性。它可能设置为DateTimeKind.Unspecified

由于您明确说明您的应用程序使用UTC,因此这些值应该为DateTimeKind.Utc。设置完成后,WebAPI将在时间戳结束时正确发出Z

在服务器端代码的某处,您应该执行以下操作:

dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);

你应该尽早这样做。例如,从数据库中检索值时,在数据访问层中。如果那是不可能的,那么至少你应该在API控制器中执行它,以便正确地发出值。

另请参阅DateTimeKindDateTime.SpecifyKind的MSDN参考。

此外 - 您获得浏览器不一致的原因是因为您使用Date对象的构造函数而不是moment内置的解析函数。虽然时刻会接受Date,但有几个已知的问题和浏览器支持从字符串解析Date的方式不一致。其中一些不一致的内容记录在案here

答案 2 :(得分:0)

使用此:

 var lastLoginTime = moment(user.lastLoginTime).fromNow();