javascript 在 moment.js fromNow() 或 from() 中使用时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18752366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 13:05:36  来源:igfitidea点击:

Using timezones with moment.js fromNow() or from()

javascriptdatetimetimezonemomentjs

提问by Click Upvote

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.

发生动作的日期+时间存储在服务器上,位于服务器的时区。这就是造成问题的原因,因为如果用户计算机的时区比服务器的时区早 12 小时,那么如果用户现在添加某些内容,moment.js 将显示“12 小时前”作为输出fromNow()而不是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, timeAgostill shows the difference between the client's timezone and the server's timezone (i.e showing '12 hours ago' instead of 'now');

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

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

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

回答by Matt Johnson-Pint

Ideally, you would want to pass a UTC timestamp from your server to the client. That doesn't mean you have to switch your whole server over to UTC, it just means that you would convert from the time in your database to UTC on the server before sending it over the web. Sure, it would be even better if you actually storedtimes in UTC, but you said you aren't in a position to make that sort of change right now. But let's just work off the assumption that you can't change anything at all on the server.

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

We'll also assume that your server is fixedto the UTC-07:00 offset. In real life, this would only be true for places like Arizona that don't follow daylight saving time. So if you are in Los Angeles and are in Pacific Time, then some of your data is based on UTC-07:00, but some of it is based on UTC-08:00. That requires a lot more work if you want to do it in JavaScript.

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

Let's also assume that the input is already a string in ISO8601 format. (If it's not, then let me know and I will adjust this code.)

我们还假设输入已经是 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();

The reason your other code didn't work is because in the first line, you are affected by the time zone of the browser. The zone setter in the second line just changes the zone for formatting, not changing the actual moment in time.

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

Also, when you dump a moment to the console for debugging, make sure you format it for output. Otherwise you are just looking at its internal property values, which may or may not make sense directly.

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

回答by fran

I have solved it in a different way, maybe this option was not possible back when the question was asked, but might be easier now.

我以不同的方式解决了它,也许在提出问题时无法使用此选项,但现在可能更容易。

I used moment-timezone.js(which requires moment.js2.6.0+).

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

I set de default timezone to my server's timezone like this:

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

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

and then just use it normally. fromNow()will use the timezone in the client to calculate the time that has passed since that moment.

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

moment(myDatetime).fromNow();

回答by Kirsten

i had the same issue and used the above comments to modify my code. I did the following to get it resolved:

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

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

I was missing the .utc() to convert it before I applied the .fromNow()

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

Things to note this is being used within a Pipe for Ionic 3 and the above code is from the pipe logic.

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