What is the best way to get client's timezone and convert it to some other timezone when using moment.js and moment-timezone.js
I want to find out what is clients timezone and later convert his date and time into some other timezone.
Does anybody has experience with this?
When using moment.js, use:
var tz = moment.tz.guess();
It will return an IANA time zone identifier, such as America/Los_Angeles for the US Pacific time zone.
It is documented here.
Internally, it first tries to get the time zone from the browser using the following call:
Intl.DateTimeFormat().resolvedOptions().timeZone
If you are targeting only modern browsers that support this function, and you don't need Moment-Timezone for anything else, then you can just call that directly.
If Moment-Timezone doesn't get a valid result from that function, or if that function doesn't exist, then it will "guess" the time zone by testing several different dates and times against the Date object to see how it behaves. The guess is usually a good enough approximation, but not guaranteed to exactly match the time zone setting of the computer.
var timedifference = new Date().getTimezoneOffset();
This returns the difference from the clients timezone from UTC time.
You can then play around with it as you like.
All current answers provide the offset differece at current time, not at a given date.
moment(date).utcOffset() returns the time difference in minutes between browser time and UTC at the date passed as argument (or today, if no date passed).
Here's a function to parse correct offset at the picked date:
function getUtcOffset(date) {
return moment(date)
.subtract(
moment(date).utcOffset(),
'minutes')
.utc()
}
Using Moment library, see their website -> https://momentjs.com/timezone/docs/#/using-timezones/converting-to-zone/
i notice they also user their own library in their website, so you can have a try using the browser console before installing it
moment().tz(String);
The moment#tz mutator will change the time zone and update the offset.
moment("2013-11-18").tz("America/Toronto").format('Z'); // -05:00
moment("2013-11-18").tz("Europe/Berlin").format('Z'); // +01:00
This information is used consistently in other operations, like calculating the start of the day.
var m = moment.tz("2013-11-18 11:55", "America/Toronto");
m.format(); // 2013-11-18T11:55:00-05:00
m.startOf("day").format(); // 2013-11-18T00:00:00-05:00
m.tz("Europe/Berlin").format(); // 2013-11-18T06:00:00+01:00
m.startOf("day").format(); // 2013-11-18T00:00:00+01:00
Without an argument, moment#tz returns:
the time zone name assigned to the moment instance or
undefined if a time zone has not been set.
var m = moment.tz("2013-11-18 11:55", "America/Toronto");
m.tz(); // America/Toronto
var m = moment.tz("2013-11-18 11:55");
m.tz() === undefined; // true
You can also get your wanted time using the following JS code:
new Date(`${post.data.created_at} GMT+0200`)
In this example, my received dates were in GMT+0200 timezone. Instead of it can be every single timezone. And the returned data will be the date in your timezone. Hope this will help anyone to save time
if the user's timezone is all you wanted then
const localtz = moment.tz.guess() // returns user's timezone
Additionally if you wanted to use it then the best way to convert a timestamp to user's timezone is
const time = moment.tz(response.timestamp)
const localtz = moment.tz.guess() // user's timezone
const date = time.clone().tz(localtz) // convert time to user's timezone
here localtz is the user's timezone and using it we can convert the timestamp to user's local time
First, you can find out the clients time zone using the following
let zoneVal = moment().tz(Intl.DateTimeFormat().resolvedOptions().timeZone).format('Z')
it will return you the GMT zone format for example +5:30 (colombo/srilanka & Delhi/India) or +6:00(Dhaka Bangladesh) depending on the region you are in.
secondly,
if you want to find out the time of a particular time zone , then do the following
moment.tz("Asia/Dhaka").format()
which will return you the time zone value in ISO format of Dhaka.
Using moment timezone you can get easily your local date-time
moment().utcOffset(0, true).format()
I am trying to show time based on user local time zone. Server saves time to utc.
So, I have a date-time saved in my database.
2018-10-03 05:55:51 // my server is digital ocean
So now I am trying to console user local time. My time zone is set to
Sylhet Bangladesh
Time offset is -360
var offset = new Date().getTimezoneOffset();
console.log(offset) // offset is -360
var testDateUtc = moment.utc("2018-10-03 05:55:51");
var localDate = moment(testDateUtc).utcOffset(offset);
console.log(localDate.format("YYYY-DD-MM hh:mm:ss"));
The above code prints incorrect date but correct time.
2018-02-10 11:55:51 the date is wrong.
I then changed my mac's time zone to Dubai which is 2 hours different then my country
For dubai the offset is -240 and it shows time
2018-03-10 01:55:51 this mean the date is correct but time is not correct.
Please help. Thank you.
EDIT
It works for most of the countries I tested like this
offset = Math.abs(offset) so it always make it positive
You do not need to think about the offset. Moment can do that for you:
moment.utc("2018-10-03 05:55:51").local().format()
Also, keep in mind that when you asked for the offset in your code, you asked for the current offset, which may or may not be the offset in effect at the time you're converting. See "Offset != Time Zone" in the timezone tag wiki.
I am having trouble when converting from time zone to time zone using moment.js.
This is my code:
convertSelectedTimeZoneToClients() {
let timeZoneInfo = {
usersTimeZone: this.$rootScope.mtz.tz.guess(),
utcOffset: this.formData.timeZone.offset,
selectedDateTime: this.toJSONLocal(this.formData.sessionDate) + " " + this.formData.sessionTime
};
let utcTime = this.$rootScope.mtz.utc(timeZoneInfo.selectedDateTime).utcOffset(timeZoneInfo.utcOffset).format("YYYY-MM-DD HH:mm");
let con = this.$rootScope.mtz.tz(utcTime, timeZoneInfo.usersTimeZone).format();
return con;
}
The user picks date, time and time zone from drop downs on client page.
In timeZoneInfo object I am storing usersTimeZone (I want to be able to convert timezone that user selected on page and convert it to his local time zone).
For example user picks: 11/08/2016 01:30 and UTC+2 timezone and his timezone is UTC+1, than I want to show him in label: That is 11/08/2016 00:30 since UTC+1 is -1 hour comparing to UTC+2 timezone.
I store offsets for time zones in one object and those values are hard coded (utcOffset: this.formData.timeZone.offset).
Before I convert time form time zone to time zone I do this: get time zone -> convert to UTC time -> convert to user time zone.
What is happening is that utcTime variable has correct value. But when I pass that value and users time zone to .tz() function and using format() to get some readable value I get same time as utcTime like shown in picture:
I have read moment.js docs and by them this .tz().format() should do the work, but as you can see my result is: 2016-11-08T23:30:00+01:00.
So it gets that is should be incremented by 1 hour but how to accomplish to get: 2016-11-09T00:30 instead?
I have tried .format("YYYY-MM-DD HH:mm") as well same problem. When I use .local() function that should convert from utc time to specified time zone same problem is present.
Am I getting something wrongly? I am pretty sure that when you convert from 2016-11-08T23:30 UTC to UTC+1 it should be 2016-11-09T00:30, or one hour forward. Does someone sees something strange in this code?
I have users who's local timezone can be different from a facility they are setting up event start times for. I want to take the time (say 10 am) and change the javascript date object to be 10am in the facility timezone and not the local timezones. I do know the utc offset of both local and desired timezone. I have not been able to link it all together. Here is my example.
var localOffset = 420;
var desiredOffset = 360;
var eventStartDate = moment(localStartDate);
eventStartDate.subtract(localOffset - desiredOffset);
my original time is in MDT and my desired is CDT but the start time of 10am needs to remain the same. If I can do this without using momentjs that is fine.
Take a look at the documentation for the subtract method:
http://momentjs.com/docs/#/manipulating/subtract/
You're missing a unit in your call. It appears that you're using minutes, so your call should be something like:
eventStartDate.subtract(localOffset - desiredOffset, 'minutes');
I'm trying to time out email messages based on user preferences. My morning calculations are working correctly but it's the evening emails that are never getting sent because dates aren't behaving as expected.
First, here's the code I'm using to grab the time and perform adjustments based on user location, etc.
var time = moment();
var machineTZ = time.zone();
var userTZ = 420;
var diffTZ = userTZ - machineTZ;
var oneHour = moment(time).add('minutes', 60);
var morningRun = moment().startOf('day');
morningRun.hour(7).minute(0);
morningRun.add('minutes', diffTZ);
var eveningRun = moment().startOf('day');
eveningRun.hour(19).minute(30);
eveningRun.add('minutes', diffTZ);
I'm checking every hour to see if it's time to schedule another email to go out. Right now this is hard-coded, but when I begin to add user preferences they'll be able to select their local time they'd like things to go out at.
I've been debugging my values to troubleshoot. Here's output from a job that ran early morning (from the server's perspective):
lastRun: 2013-10-12T00:06:55.088Z (this one is being run at 1 am)
morningRun: 2013-10-11T14:00:00.000Z
eveningRun: 2013-10-12T02:30:00.000Z
The run numbers are as I would expect them to be. In two hours time I want the evening email to go out (7:30pm my time = 2:30am the following day server-time).
Looking again an hour later we see:
lastRun: 2013-10-12T01:06:58.267Z (this one is at 2 am)
morningRun: 2013-10-12T14:00:00.000Z
eveningRun: 2013-10-13T02:30:00.000Z <---- what?
All of a sudden my calculation for my evening has flipped over the date line, even though it's still 10/12 (not 10/13 yet). Because of this my check to see if I should schedule the email fails since it now thinks I need to send the email in 24 hours, not 30 minutes.
Been battling with this weird inconsistency for a while, I thought I had figured out why it was doing it and adjusted my calculations using the time zone stuff above but that didn't do the trick :(. This certainly seems like some sort of weird bug as I would expect this to be happening:
//Today is 10/12
var eveningRun = moment().startOf('day'); //10/12/2013 - 00:00:00
eveningRun.hour(19).minute(30); //10/12/2013 - 19:30
eveningRun.add('minutes', diffTZ); //10/13/2013 - 2:30 am
This works until at some point it decides that "today" is actually 10/13 and sets the evening run is to take place on 10/14 instead. Help is greatly appreciated, or if this is a bug would love to know what I can do to work around this issue until it's resolved.
There's no need to calculate machineTZ, diffTZ or add any minutes. Just do this instead:
moment().zone(userTZ).startOf('day').hour(7).minute(0)
But do keep in mind that a value such as 420 is not a time zone, it's a time zone offset. It only tells you what the offset is for a particular point in time. Since you are applying it unilaterally, you may get incorrect results during daylight saving time.
Instead, you should try using the moment-timezone addon, and do something like this instead:
moment().tz("America/Los_Angeles").startOf('day').hour(7).minute(0)
See also the timezone tag wiki, in particular the sections titled "Time Zone != Offset" and "The IANA/Olson Time Zone Database".