My server is returning me dates in UTC and I want to convert them to the timezone of the server (even if the customer browser is in a different timezone !)
Here is one example, my server is in Europe/Berlin.
var dateAsString = '2022-04-11T22:00:00.000Z'; // 2022-04-12 00:00:00 in Europe/Berlin
var utcDate = moment.utc(dateAsString);
console.log(utcDate.format());
var serverTzDate = utcDate.clone().tz('Europe/Berlin');
console.log(serverTzDate.format());
console.log(serverTzDate.format());
var test = moment.utc('2022-04-11T22:00:00.000Z').tz('Europe/Berlin').format();
console.log(test);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.34/moment-timezone-with-data-10-year-range.js"></script>
If my browser is in the Europe/Berlin timezone the output is correct:
2022-04-11T22:00:00Z
2022-04-12T00:00:00+02:00
2022-04-12T00:00:00+02:00
But if I change my timezone (for my example I took Pacific/Niue), then the result is totally wrong, I suppose moment is doing something with the timezone of the browser but how to avoid this ? Here is the output:
2022-04-11T09:00:00Z
2022-04-11T11:00:00+02:00
2022-04-11T11:00:00+02:00
I need to have the date in the timezone of the server and not in the timezone of the browser
With another timezone: Pacific/Kiritimati (-840)
2022-04-12T10:00:00Z // Wanted 2022-04-11T22:00:00Z (UTC Date as entered)
2022-04-12T12:00:00+02:00 // Wanted 2022-04-12T00:00:00Z (Converted in Europe/Berlin)
2022-04-12T12:00:00+02:00 // Wanted 2022-04-12T00:00:00Z (Converted in Europe/Berlin)
2022-04-12T12:00:00+02:00 // Wanted 2022-04-12T00:00:00Z (Converted in Europe/Berlin)
Again all the dates are wrong, moment seems not able to parse my date as an UTC date ? It apply the timezone offset of the browser even if I'm using the utc method
moment.utc('2022-04-11T22:00:00.000Z').tz('Europe/Berlin').format()
please check this document. https://momentjs.com/timezone/docs/#/using-timezones/
below is my code result, whatever timezone you changed, the result is '2022-04-12T00:00:00+02:00'
Related
Im currently testing out running a server with routes etc. and am trying to display the date of the previous person to request that route. Usually when i use the new Date() object i get it in my local time, but for some reason it is displaying it in UTC (coordinated universal time) and im not sure how to change it.
my code is
var date;
var dateArr = [];
var counter = 0;
router.get('/last.txt', function(req, res) {
counter++;
date = new Date().toString();
dateArr.push(date);
if (counter == 1) {
res.send("");
} else {
res.send(dateArr[counter-1]);
}
});
but i keep receiving the date in the format:
Fri Mar 26 2021 07:24:50 GMT+0000 (Coordinated Universal Time)
Any advice would be appreciated!
EDIT: I live in Australia so i think it usually outputs in AEDT
It would appear that UTC is the timezone in place for the server where this code is running. That's fine, you can convert that to the local timezone on the client quite easily. Rather than using toString, though, I would store either the Date object, or its time value (the result of .valueOf()), or the result of .toISOString() and then send either the time value (a number) or the ISO string value to the client. That way, you're not relying on the timezone of the server. When you pass either of those (the time value or the ISO string) into new Date on the client site, the resulting Date will have the same date/time, but because it's operating in the client's timezone, its local time formatting methods like toString, getFullYear, etc., will use the local timezone of the client.
E.g., change toString to (for instance) toISOString in your code, and on the client:
const dt = new Date(theStringFromTheServer);
console.log(dt.toString()); // Will use the client's timezone to show the date/time
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()
My customer's store is in GMT +5:30 timezone but the user's locale is in GMT +8 timezone.
Currently, I'm using javascript's .toISOString() function to convert to UTC and storing UTC in the database. I retrieve UTC from the database and send exactly that the browser, so the new Date('2019-11-15T00:00:00Z') function converts the UTC to the browser's locale.
But, if the user opens a record created by GMT +8 timezone user or vice-versa, the dates are getting messed up.
I'm thinking it would be good if I can transfer the exact date the user enters in the browser and send that exact date to the backend to easily offset using the store's timezone?
The frontend is in VueJs and the backend is in C#.
Always store UTC time in database
Just Store the UTC time in your database, In your client-side, Get client's current timezone,
Here, I am getting IANA timezone from client's system
// get client's timezone (From user's system)
var clientTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
Then, Convert the UTC depends on the timezone and show it to user,
// assume 2019-11-15T00:00:00Z is the UTC date from your database
var convertedTime = new Date('2019-11-15T00:00:00Z').toLocaleString("en-US", {timeZone: clientTimezone});
Example
var clientTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
var timeUtc = '2019-11-15T00:00:00Z';
var convertedTime = new Date(timeUtc).toLocaleString("en-US", {timeZone: clientTimezone});
console.log("Time to Current User : " + convertedTime);
var timeInUsa = new Date(timeUtc).toLocaleString("en-US", {timeZone: "America/New_York"});
console.log("Time in America (New York) : " + timeInUsa);
var timeInAustralia = new Date(timeUtc).toLocaleString("en-US", {timeZone: "Australia/Brisbane"});
console.log("Time in Australia (Brisbane) : " + timeInAustralia);
Note that the js Date object is simply a number that represents an absolute time (independent of any timezone).
So the best encoding/format for transferring and storing a date is that number. IMO this is much simpler than storing a UTC string.
So, on the end-user's machine you would Date.parse the date string provided by the user and this would take account of the user's time zone for you and give you the absolute time number for sending and storing on your backend.
Don't do any formatting or parsing of dates on the backend if you are using Node because there are serious gotcha's and because you shouldn't need to anyway: any client device that needs a date string will do the formatting locally which will automatically convert it to the correct format for their locale and timezone. [edit: the Q did not specify the backend when I wrote this.]
You will need to watch for some gotcha's in the Date.parse function but these are minor compared to the node problems. The most significant IMO is that it will interpret dates in YYYY-MM-DD as ISO 8601 dates (which makes some sense) but then assume that they are GMT if no timezone is specified so you should make sure there is a timezone specified if you use that format.
I'm working in an Angular 6 front end and receive from another system time stamps which have no time zones (C# backend, DateTime). I suspect that javascript is automatically adding the local time zone to Date objects.
Example:
Receiving from backend: 2018-10-15T07:53:00.000Z
When console logging: console.log(timestamp) // Mon Oct 15 2018 09:53:00 GMT+0200
I am using moment.js and already tried moment.utc() and moment(DATE).utc(). But it still adds the local time zone especially because I have to re-transform my moment objects back to the type Date with .toDate().
How can I resolve the time zone difference and get back a utc date to work with or the same structure as received?
try to format use as per desired.
let str = '2018-10-15T07:53:00.000Z';
let moment = moment(str).utcOffset(str)
console.log(moment.format('DD/MM/YYYY HH:mm'))
<script src="https://momentjs.com/downloads/moment.js"></script>
Second Snippet (to use the date object from string)
let str = '2018-10-15T07:53:00.000Z';
let moment = moment(str).utcOffset(str);
console.log(moment.toDate())
<script src="https://momentjs.com/downloads/moment.js"></script>
Your input is UTC and will be parsed just fine. Javascript Dates have no notion of timezone! The local timezone is applied by the static methods for serializing (Date.toString(), Date.toDateString() etc.) (Console.log(Date) uses Date.toString().)
Use Date.toLocaleString([],{timeZone:"UTC"}). Forcing UTC, you will see in the output the same time as the input. Much more details are here :-)
Here it is working:
console.log(new Date('2018-10-15T07:53:00.000Z').toLocaleString([],{timeZone:'UTC'}))
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()