I am using Moment.js to handle dates in my web application. The server returns all the dates in milliseconds UTC. Now, I have to display the dates applying a specific timezone (based on the user settings).
Is there any way to set the timezone globally instead of changing all the calls to momentjs to handle it?
You can set the default timezone in Moment by using:
moment.tz.setDefault(String);
For example
moment.tz.setDefault("America/New_York");
npm install moment-timezone
var moment = require('moment-timezone'); and use this object
instead of usual moment.
moment.tz.setDefault(String); where String is a time zone
identifier.
For example:
var moment = require('moment-timezone');
moment.tz.setDefault("America/New_York");
Docs: https://momentjs.com/timezone/docs/
Use the moment-timezone library found on the same website: http://momentjs.com/timezone/
It let's you do things like:
moment(utcDateTime).tz(settings.timezone).format(settings.dateFormat);
I recommend implementing a user class/object that has a service function for translating UTC to the user's timezone. Have a look at this fiddle:
http://jsfiddle.net/guidosch/ofd4unhu/4/
The dates are served as UTC, but the view uses the date formatting method of the user class to adjust and format the UTC date according to the user's preferences.
Having run into this problem in the past, my solution was to create a moment factory that provisioned moment objects rom a base configuration. You can make it as transparent as requiring moment - referencing your package and using the class just like moment - but in reality you are calling a moment wrapper object that provisions the moment implementations with the selected timeZone.
I've not done extensive testing, but it looks right on cursory tests. I was able to do this with Moment Timezone 0.0.1:
var serverTimezoneOffset = <?php echo timezone_offset_get(new DateTimeZone(date_default_timezone_get()), new DateTime('now')) / -60; ?>;
moment.updateOffset(new Date().getTimezoneOffset()-serverTimezoneOffset);
Related
So I have this use case where a user should be able to enter data into a react site having an order_fulfilment_datetime_str which is supposed to be a RFC 3339 datetime string according to the specs of the api this would be posted to.
So essentially a user(in any timezone) selects a (future) date and time (using a plugin such as react-datepicker) assuming that the date time is going to be in PST/PDT.
But the plugin and javascript date object returns the selected date time in the browser's timezone. So I have two things to solve:
How do I make sure that selected date/time is in PST/PDT
How to deal with DST?
Currently what I am trying to do is to simply get individual date, hours, minutes using getHours(), getMinutes(), getDate() to form the string. But again then how will I find out if this selected datetime has offset of -8 or -7(i.e. PST/PDT)?
I checked date-fns and date-fns-tz library but was not sure how to solve this issue using these.
You can use luxon library for setting a global timezone that you want, and then whenever a user selects a date-time using a date-time picker you can simply convert that into the timezone you want.
import { Settings } from "luxon"
Settings.defaultZone = <time-zone>
The above code snippet will set a default zone for the app
Now when a user selects a date-time convert it to the timezone you want using the below code
DateTime.fromISO(dateTimeValue, { setZone: true})
I have a server storing timestamps in one timezone and users living in a another timezone. I had the impression that momentjs timezone acted as a kind of decorator, and if I defined a timezone
moment.tz.setDefault("Europe/Copenhagen");
then subsequently usage of moment functions will use timezone defined
var date = moment(timestamp_from_server).calendar()
In my case adding one hour to all timestamps. But obviously does that not work.
Is it possible to set a "global" or app-wide timezone, so I not have to convert each and every timestamp in code, and just can rely on momentjs methods? Any suggestion, also alternatives is highly appreciated.
Note: I am using AngularJS, setting timezone in
app.run(function(...) {
...
moment.tz.setDefault("Europe/Copenhagen")
})
but I don't think that have any importance.
You can achieve this using angular moment
If you don't want to use this module
You can create a factory or service for momentjs and use dependency injection to use everywhere in the application
Create a decorator that will set the default timezone, this will help for a consistent timezone in entire application.
Update based on comments:
If you start a new project from scratch it may be easier to use angular moment
othrewise the decorator or app.run or setting in service itself is very eassy. but when applying a timezone in an existing project make sure that the change in timezone is not affecting the existing date functions using momentjs
A simple implementation of setting default timezone with factory
Since factory is singleton it will be created only one
https://embed.plnkr.co/wmv11KEuJt6XJvgs5eY8/
We're trying to find a problem with tests that use moment.js and fail when run on a server in Arizona but succeed when run locally here in the UK. We manually set the locale before creating a moment and can see that the local 'en-gb' is installed.
This fiddle highlights what I think the problem is (Need to set computer to Arizona Time zone first!) https://jsfiddle.net/2ve10ax4/
moment.locale('en-gb');
console.log(moment.locale());
// en-gb
console.log(moment('2016-05-01T00:00:00+00:00').format());
// 2016-04-30T17:00:00-07:00
I'm expecting to see the date formatted with respect to 'en-gb' locale but it shows it with respect to Arizona time. Am I missing something?
Locale and timezone are orthogonal things. A locale does not specify a timezone unambigously. You need to set your timezone separately. You can use Momemt Timezone, and then you can use e.g.
.tz('Europe/London')
By setting moment.locale('en-gb') you have specified a locale/language (brittish-english), not a timezone.
To specify a timezone you need to include the Moment.js Timezone library in your project, and then do something like:
console.log(moment('2016-05-01T00:00:00+00:00').tz('America/Phoenix').format());
The above will give you the timezone for Arizona.
After reading more I believe parseZone is the correct solution, given that I am already including Time Zone information in the date string.
console.log(moment.parseZone('2016-05-01T00:00:00+00:00').format());
I'm using momentjs lib to updated text on some ajax action. What I need to do is to set a current date & time in london. I'm using moment.utc() function but because of the summer time I'm one hour out.
For example running this on 14:26
console.log( moment.utc().format('HH:mm:ss') );
I'm getting 13:26:53.
Any idea on how to fix this?
Can you use momentJS timezone?
moment().tz('Europe/London');
EDIT: In case you try to use this without seeing the link, it's a separate library you have to include.
If you want the local time instead of the UTC time, just use moment() instead of moment.utc(). You're specifically asking for UTC, so you shouldn't be surprised when you get UTC :)
From the documentation:
By default, moment parses and displays in local time.
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment().
This brings us to an interesting feature of Moment.js. UTC mode.
While in UTC mode, all display methods will display in UTC time instead of local time.
This is assuming you always want the user's local time. If you want a specific time zone (London) which may not be the user's time zone and isn't UTC, then you should use the library indicated by Takuya's answer. I would think carefully before doing so though - while it may be a sensible approach, you should at least validate that first. It's often reasonable to display a time for user U1 in the time zone of user U2 - but here you're using a fixed time zone. That's only appropriate if you know that U2 will always be in London. It would be really confusing if actually U2 is in some other zone - either the same as or different to U1.
From my understanding, Arshaw FullCalendar displays events according to the timezone of the local computer's operating system. I assume this is done by the javascript Date() object, which also is based on the local computer's operating system. I have an application that has group calendars and a group timezone, I want to be able to force every local Arshaw Calendar to display according to that group's time-zone, no matter what timezone that computer is. How do you do this?
Note: I've looked through the documentation fairly thoroughly, and found no such option. I'm hoping that javascript has something equivalent to php's date_default_timezone_set(), which seems to me the way this could be solved.
*Edit 1/31/2013 12:23pm CST:
I am sending everything to the calendar as unix timestamps, so I assume the option ignoreTimezone would not apply here, as described in this stackoverflow thread:
jQuery FullCalendar timezone synchronization
You should probably try to set the option "ignoreTimezone" to "false" and give to Arshaw FullCalendar date in ISO8601.
You can get more information about that here: http://arshaw.com/fullcalendar/docs/event_data/ignoreTimezone/
To convert unix timestamps to ISO8601, you can use this in javascript:
var d = new Date(1360412434000).toISOString();
This is ECMAScript 5.
See here for compatibility and fallback code: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString