My app is logging certain user events for display in the UI. The timestamps are being stored as dates in Mongo, which bee JS Date object, with timezone information relative to the server's timezone.
I'm using moment.js to format the dates, but since my users are in Australia and my app is hosted on Heroku (server timezone is UTC), the 'local' time that moment.js helpfully outputs aren't what my users want to see.
Moment.js allows you to switch between UTC and 'local' time (on the server), but doesn't seem to let you output in the context of a different timezone.
(Changing the server's timezone not solve the underlying issue, it would also be wrong for some of my users.)
I have tried to use the node-time library to change the timezone on the date, which does work if I then simply output the timestamp using Date.toString(), but if the date is wrapped by Moment.js, it reverts back to the server's timezone.
I could wrangle a solution by calculating the difference between user-local timezone and server-local timezone and modifying the date before it is formatted by Moment.js, but I am hoping there is either (a) a more elegant solution, or (b) a good library that will do this.
I could also output the dates in UTC and let a client-side library reformat them, but I would prefer to have a server-side solution.
Does anybody know of a good solution to this, or a library that fills this gap for Node.JS apps? Is there an established best practice for this?
My app is logging certain user events for display in the UI. The timestamps are being stored as dates in Mongo, which bee JS Date object, with timezone information relative to the server's timezone.
I'm using moment.js to format the dates, but since my users are in Australia and my app is hosted on Heroku (server timezone is UTC), the 'local' time that moment.js helpfully outputs aren't what my users want to see.
Moment.js allows you to switch between UTC and 'local' time (on the server), but doesn't seem to let you output in the context of a different timezone.
(Changing the server's timezone not solve the underlying issue, it would also be wrong for some of my users.)
I have tried to use the node-time library to change the timezone on the date, which does work if I then simply output the timestamp using Date.toString(), but if the date is wrapped by Moment.js, it reverts back to the server's timezone.
I could wrangle a solution by calculating the difference between user-local timezone and server-local timezone and modifying the date before it is formatted by Moment.js, but I am hoping there is either (a) a more elegant solution, or (b) a good library that will do this.
I could also output the dates in UTC and let a client-side library reformat them, but I would prefer to have a server-side solution.
Does anybody know of a good solution to this, or a library that fills this gap for Node.JS apps? Is there an established best practice for this?
Share Improve this question edited Jan 9, 2013 at 14:25 Jed Watson asked Jan 9, 2013 at 14:08 Jed WatsonJed Watson 20.4k3 gold badges35 silver badges43 bronze badges 4- May be helpful: developer.mozilla/en-US/docs/JavaScript/Reference/… – Paul S. Commented Jan 9, 2013 at 14:25
-
It's generally best to leave everything as UTC on the node.js/server/API side and convert to the user's TZ for presentation using JavaScript in the browser using the standard
Date
methods that are aware of the user's local time zone. – JohnnyHK Commented Jan 9, 2013 at 14:33 - @JohnnyHK I'm looking for a way to do it server-side for a few reasons, including displaying dates relative to a user's known timezone (not necessarily the browser's). Otherwise I generally agree with you. – Jed Watson Commented Jan 9, 2013 at 14:47
- @PaulS. if I do end up creating a module to do this, that will definitely help. Cheers. – Jed Watson Commented Jan 9, 2013 at 14:48
2 Answers
Reset to default 6I ended up figuring out how to use both the node-time and moment.js libraries to create a relatively elegant solution to this.
I created a module moment_tz.js like such:
var moment = require('moment'),
time = require('time');
exports = module.exports = function(t,z) {
var tz = new time.Date(0, z);
return moment(t).add('minutes', t.getTimezoneOffset() - tz.getTimezoneOffset());
}
It returns a moment
object that has been updated with the difference (in minutes) between the two timezones.
Here's how I'd use it to output the current time in Sydney:
moment_tz(new Date(), 'Australia/Sydney').format('Do MMM \'YY - h:mm:ss a')
If anybody has a better solution, please let me know!
Cheers.
I know its a old post, still this might help someone MomentJs has a timezone feature now.
http://momentjs./timezone/
var time = moment.tz(new Date(), timezone_string) /* timezone_string = "Australia/Sydney" */
var timestring = time.format('D/MM/YYYY hh:mm A')
Hope this helps.