14

I want to show users how long has been elapsed since they performed an action.

The date+time of the action happening is stored on the server, in the server's timezone. That's what's causing the trouble, since if the user's computer's timezone is 12 hours ahead of the server's timezone, then if the user adds something right now, moment.js will show '12 hours ago' as the output of fromNow() rather than just now.

To try to solve this, I'm trying the following method:

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

But despite of all this, timeAgo still shows the difference between the client's timezone and the server's timezone (i.e showing '12 hours ago' instead of 'now');

Anyone know how to fix this or what I'm doing wrong?

4

3 回答 3

14

理想情况下,您希望将 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();

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

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

于 2013-09-12T01:10:12.440 回答
14

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

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

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

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

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

moment(myDatetime).fromNow();
于 2015-07-06T14:43:28.060 回答
1

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

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

在应用 .fromNow() 之前,我错过了 .utc() 来转换它

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

于 2017-08-01T07:06:29.297 回答