Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 531
Ali Avatar asked Sep 11 '13 22:09

Ali


People also ask

How do you set timezone with moment?

To change the default time zone, use moment. tz. setDefault with a valid time zone.

Does moment timezone include moment?

Moment-timezone is a separate npm module from moment, but moment-timezone depends on moment under the hood. So you can install moment-timezone by itself, or both moment and moment-timezone. Once you install moment-timezone, you can require() it in and use it like you would use moment.

Does moment use UTC by default?

utc(Date); By default, moment parses and displays in local time. If you want to parse or display a moment in UTC, you can use moment.

Is moment timezone deprecated?

This format is deprecated and will be removed in future.


1 Answers

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 stored times 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.

We'll also assume that your server is fixed to 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.

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

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.

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.

like image 172
Matt Johnson-Pint Avatar answered Sep 19 '22 20:09

Matt Johnson-Pint