【问题标题】:Using timezones with moment.js fromNow() or from()将时区与 moment.js fromNow() 或 from() 一起使用
【发布时间】:2013-09-16 03:17:54
【问题描述】:

我想向用户显示他们执行某项操作后已经过去了多长时间。

动作发生的日期+时间存储在服务器上,在服务器的时区中。这就是造成问题的原因,因为如果用户计算机的时区比服务器的时区早 12 小时,那么如果用户现在添加一些内容,moment.js 将显示“12 小时前”作为fromNow() 的输出而不是@ 987654322@.

为了解决这个问题,我正在尝试以下方法:

var actionTime = moment( action.timeStamp);//time of when user performed action 
var serverTime = moment().zone('-07:00'); //current server time

console.debug( serverTime);//outputs Wed Sep 11 2013 15:19:51 GMT-0700

var timeAgo = serverTime.from( actionTime);

尽管如此,timeAgo 仍然显示客户端时区和服务器时区之间的差异(即显示“12 小时前”而不是“现在”);

有人知道如何解决这个问题或我做错了什么吗?

【问题讨论】:

  • 您最好先在服务器上转换为 UTC 并与之进行比较。这可能吗?
  • 另外,action.timestamp 是什么格式的?
  • @MattJohnson 它最初是一个 mysql DATETIME 字符串,但我使用 Moment 对其进行格式化以从中生成一个 Moment 对象。将服务器更改为使用 UTC 是非常有问题的,所以我想尽可能避免这种情况。有没有办法让这项工作像现在一样?
  • 是的,您可以立即完成。我现在是移动设备,但稍后我会发布一个示例。你能显示输入的确切字符串吗?这非常重要。另外,您的服务器是否在像亚利桑那州这样的固定时区?或者你现在在太平洋夏令时间?再次,它确实很重要。通常这就是它在服务器代码中完成的原因。
  • 我还没收到你的回信就回家了,所以我做了一些假设。如果您有不同的做法,请告诉我,我会做出相应调整。

标签: javascript datetime timezone momentjs


【解决方案1】:

理想情况下,您希望将 UTC 时间戳从服务器传递到客户端。这并不意味着您必须将整个服务器切换到 UTC,它只是意味着您将在通过网络发送之前将数据库中的时间转换为服务器上的 UTC。当然,如果您实际上存储时间在 UTC 中会更好,但您说您现在无法进行这种更改。但是,让我们假设您根本无法更改服务器上的任何内容。

我们还将假设您的服务器固定到 UTC-07:00 偏移量。在现实生活中,这只适用于像亚利桑那州这样不遵循夏令时的地方。因此,如果您在洛杉矶并且处于太平洋时间,那么您的一些数据基于 UTC-07:00,但其中一些数据基于 UTC-08:00。如果你想在 JavaScript 中做这件事,那需要做更多的工作。

我们还假设输入已经是 ISO8601 格式的字符串。 (如果不是,请告诉我,我会调整此代码。)

var s = "2013-09-11 18:00:00";  // from action.timeStamp

var actionTime = moment(s + "-07:00", "YYYY-MM-DD HH:mm:ssZ");

var timeAgo = actionTime.fromNow();

您的其他代码不起作用的原因是因为在第一行中,您受到浏览器时区的影响。第二行中的区域设置器只是更改格式化区域,而不是更改实际时间。

此外,当您将片刻转储到控制台进行调试时,请确保将其格式化以进行输出。否则,您只是查看其内部属性值,这可能直接有意义,也可能没有意义。

【讨论】:

  • 谢谢马特,我想我必须手动添加/减去小时数,但我不知道该怎么做。一个问题,假设服务器的时区是 GMT -7(山区),而用户在 GMT +2,那么为了向用户显示正确的“fromNow”,我必须首先了解服务器和用户时区(+2 -7 = -5),并从 actionTime 中减去 -5 小时,对吗?有没有办法将其更改为基于此减去?
  • 您不必考虑客户的时区。您要求客户的唯一事情是“现在”,它基于 UTC 与时刻或Date
  • 当你将偏移量传递给时刻构造函数时,你说的是“这个时刻在这个偏移量中”。但从那时起,它就是一个特定的时刻。如果你加或减,你将谈论一个不同的时刻。
  • 我明白了.. 但你确定吗?例如,如果我只是做moment(),我会在客户的计算机上获得当前日期,还是会根据 UTC 获得日期?
  • moment() 就像new Date()。它在内部跟踪 UTC,同时在本地时间输出和解析。所以答案是两者都,这取决于你如何看待它。
【解决方案2】:

我已经用不同的方式解决了这个问题,也许这个选项在被问到问题时是不可能的,但现在可能更容易了。

我使用了moment-timezone.js(需要moment.js 2.6.0+)。

我将默认时区设置为我的服务器的时区,如下所示:

moment.tz.setDefault("America/New_York"); // "America/New_York" in my case

然后就可以正常使用了。 fromNow() 将使用客户端中的时区来计算从那一刻起经过的时间。

moment(myDatetime).fromNow();

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,并使用上述 cmets 来修改我的代码。我做了以下事情来解决它:

      transform(value: string) {
        var time = moment(value).utc();
        return moment(time, "YYYYMMDD").fromNow();
      }
    

    我在应用 .fromNow() 之前缺少 .utc() 来转换它

    需要注意的是,这是在 Ionic 3 的管道中使用的,上面的代码来自管道逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 2019-01-05
      • 2020-08-04
      • 2016-05-15
      • 2019-05-23
      相关资源
      最近更新 更多