3

我们愚蠢地假设一段 momentjs 代码可以在所有浏览器中运行。现在它在 chrome 中正常工作,但所有其他浏览器都没有应用 UTC 偏移量。如何使此代码在其他浏览器中始终如一地工作?现在 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 小时内”

4

3 回答 3

8

让它工作的方法:

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();

不起作用。现在想起来就说得通了。

于 2013-10-01T13:21:25.210 回答
5

原始答案

尝试这个:

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

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

扩展答案

你应该明白,当你发送一个字符串时2013-10-01T13:15:30.937,你并没有发送任何上下文。无法仅从该字符串中知道时间是 UTC,还是您服务器的时区,还是浏览器的时区。

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

正如您所发现的,您可以通过使用.utc函数(例如moment.utc("2013-10-01T13:15:30.937").

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

这些字符串采用ISO 8601 / RFC 3339格式。该规范的一部分描述了如何指示时间戳采用 UTC。您只需Z在末尾添加一个。如果您提供,Z则此时间戳的任何消费者都将知道该时间应解释为 UTC。果然,如果你直接把它传递给 moment,比如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 控制器中这样做,以便正确地发出值。

另请参阅 DateTimeKind和的 MSDN 参考资料DateTime.SpecifyKind

另外 - 你得到浏览器不一致的原因是因为你使用Date对象的构造函数而不是内置的解析函数moment。虽然 moment 将接受 a ,但浏览器如何支持从字符串Date解析 a 存在一些已知问题和不一致。此处Date记录了其中一些不一致之处。

于 2013-10-01T02:19:00.573 回答
0

用这个:

 var lastLoginTime = moment(user.lastLoginTime).fromNow();
于 2019-02-04T07:24:44.240 回答