I have a timestamp from the backend and I want to display it with momentjs per console.log() without timeshifting and completly indepented from my browsers timezone. I read many posts on stackoverflow but nothing works. All of my outputs have some timezone included.
let timestamp = "2019-11-19T07:05:00+01:00";
console.log(moment(timestamp).toISOString(true));
console.log(moment.utc(timestamp).format());
console.log(moment.utc(timestamp).toISOString(true));
console.log(moment.parseZone(timestamp).format());
console.log(moment.parseZone(timestamp).local().format());
console.log(moment.parseZone(timestamp).utc().format());
console.log(moment(timestamp).utcOffset(timestamp).toISOString(true));
console.log(moment.tz(timestamp, 'Europe/Berlin').toISOString(true));
console.log(moment.tz(timestamp, 'Europe/Berlin').format());
console.log(moment.tz(timestamp, 'Europe/Berlin').unix());
console.log(moment.parseZone(timestamp).format('MM/DD/YYYY HH:mm:ss'));
console.log(moment(timestamp).utcOffset("+0100").format('YYYY-MM-DD hh:mm:ss'));
expected output:
2019-11-19T07:05:00Z
The Timezone of the timestamp is: Europe/Berlin
My Browsers timezone is switched to something different.
I don't understand why this simple problem has no easy solution. :)
To meet the requirement you described (keeping the local time while changing the offset) you can do the following:
var result = moment.parseZone("2019-11-19T07:05:00+01:00").utcOffset(0, true).format();
console.log(result); //=> "2019-11-19T07:05:00Z"
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Step by step explained:
moment.parseZone("2019-11-19T07:05:00+01:00") // Parses the string, retaining the offset provided
.utcOffset(0, true) // sets the offset to zero while keeping the local time
.format() // formats the output, using Z to represent UTC
However - You should recognize that these are not the same moments in time. The output timestamp is one hour earlier than the input timestamp. This is explained in the documentation as follows (emphasis mine):
The utcOffset function has an optional second parameter which
accepts a boolean value indicating whether to keep the existing time
of day.
Passing false (the default) will keep the same instant in Universal Time, but the local time will change.
Passing true will keep the same local time, but at the expense of choosing a different point in Universal Time.
Thus, it is usually the wrong choice when you already have a specific point in time, either in UTC or as an offset from UTC (like your example input value).
Instead, you should expect that converting from local time to UTC will indeed change the date and time portion of the timestamp. You can use .utcOffset(0, false), or .utcOffset(0), or simply .utc() to do the conversion correctly.
Related
I am working on a web application that needs stores a start and finish value for a work shift. The application has a timezone selection component which updates any date/time values in UI to match the time in a given timezone/location by changing a timezone cookie. Values are stored in a database as UTC values and they are passed through a controller to convert them between the DB and UI.
I am working on a page that has an exception where the start and finish times are changeable/editable by the user after saving. The page will get these values from UI Date Boxes. The values can convert to UTC on saving values with no issue with use of Luxon, however, a user can navigate back to the given page to edit saved values if changes are needed. When this happens, the saved values are loaded into these DevExpress/DevExtreme date boxes but they are not displayed as expected.
The values come from an odata response and is read as response.value[0].Start. When getting the value, an offset is applied based on the users cookie location, so in my case (Europe/London timezone) the response would be 2022-05-24T01:00:00+01:00.
I can convert this to UTC using DateTime.fromISO(response.value[0].Start).toUTC() to give me a value of 2022-05-24T00:00:00.000Z which is expected.
However I am running into converting this value to the desired value for a selected timezone. I try to do so with the following:
var DateTime = luxon.DateTime;
//selectedTimeZone found from cookie.
// -- logic --
if (response.value[0].Start != null) {
var dateBox = $("#ShiftBeginning").dxDateBox('instance');
var converted = DateTime.fromISO(response.value[0].Start).toUTC().setZone(selectedTimeZone, {keepLocalTime: true});
dateBox.option({ value: converted});
}
//Example selectedTimeZone: Asia/Tokyo
//converted.toString() value: 2022-05-24T00:00:00.000+09:00 (Tokyo time zone)
//Displayed UI Time value: 16:00
//Displayed UI Time value with {keepLocalTime: false}: 01:00
It appears as if the value of converted is having the offset applied twice, with an hour then taken off of the time to represent UTC.
I have tried changing parsing this value to different formats, tested different timezones, using standard JavaScript Date object etc. and I am beginning to run out of ideas.
Any help is appreciated to help solve this.
It's being "converted" twice because the time picker doesn't respect the zone in your cookie, because it doesn't know about it. Remember that the time is the time; the zone and how the time is represented in that zone are more like metadata. So it's expressing the time in user's system zone, and the local time it displays is off from what you expect by the difference between where they are and Tokyo's local time.
What you want to do is:
find the local time in Tokyo for your time. This is probably just DateTime.fromISO(s).setZone(selectedZone). You don't want keepLocalTime because your time is correct
change to the user's system zone, but keeping the time constant, which is just converted.setZone("system", { keepLocalTime: true }). We do this because we want a local time that is, technically, wrong; it's what local time matches the right Tokyo time. This is more-or-less the purpose of keepLocalTime: to trick zone-unaware components into showing a local time in another zone.
It's a little odd that you're passing the Luxon DateTime directly to the time picker. I guess it's calling valueOf() on the value you pass in. But you'd probably want to do that yourself to be confident you're telling it the right thing.
So all together:
var converted = DateTime
.fromISO(response.value[0].Start)
.setZone(selectedTimeZone);
.setZone("system", { keepLocalTime: true });
dateBox.option({ value: converted.valueOf() });
I am using the "MongoDB for VS Code" plugin in Visual Studio Code (v1.49.0) and am trying to reset the time of a Date object to 00:00:00:000 in the MongoDB Playground.
Here is the code:
var thisMonth = new Date();
thisMonth.setDate(1);
thisMonth.setHours(0, 0, 0, 0);
thisMonth;
However, the value output for thisMonth is:
2020-09-01T06:00:00.000Z
and not 2020-09-01T00:00:00.000Z as expected. This happens regardless of when the Date object is created. Does anyone else have experience or know why this might be happening?
Thank you.
MongoDB will always use UTC time (UTC-0 or Zulu/Zero time).
The hours you set are according to your local timezone, so in this case most likely North America (UTC-6). The result is given with a Z on the end indicating it is Zulu time (zero time).
To get the offset on your local machine you can use thisMonth.getTimezoneOffset();
To set the time to UTC time you use thisMonth.setUTCHours(0);
You will see that when setting the time to UTC time 0 you will actually get the 0 result you are looking for.
MongoDB does not have an understanding of timezones.
This is not related to MongoDB but normal JavaScript behaviour. See Date#setHours():
The setHours() method sets the hours for a specified date according to local time [...].
MongoDB transforms dates into their UTC representation before storing them. And you (or your server) seem to be located in a -6:00 time zone. The actual moment in time is correct, you are just seeing a representation that might not be what you expected.
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 have a timestamp 2016-09-14T10:44:55.027Z and I would like to only display the 10:44:55 part but I'm not completely sure how. I have access to the moment library but not sure how to pass this into moment and format it, also how could I add AM or PM?
moment("2016-09-14T10:44:55.027Z").format('hh:mm:ss')
seems to output 11:44:55?
jsFiddle http://jsfiddle.net/eemfu0ym/
Since your input contains the Z suffix, that means the input value is in UTC. However, you're passing it into the default moment constructor, which is local time, thus a conversion occurs.
To keep it in UTC, the simplest way is to just obtain the moment object in UTC mode to begin with.
var m = moment.utc("2016-09-14T10:44:55.027Z")
Once you have that, you can format it however you like:
m.format('HH:mm:ss') // 24-hour clock time
m.format('hh:mm:ss A') // 12-hour time with meridiem (AM/PM)
See the moment formatting docs for other options. Do note that tokens are case sensitive.
I put a UTC .NET/JSON date from .net on client side. When I run the following command:
moment(value.Planet.when).utc()
The returned date from webservice:
"/Date(1469271646000)/"
I get a date in the _d parameter showing the current accurate UTC date with GMT+0300 on right side.
I want to convert this time to local time on the user machine and what ever I do, I always get the time 3 hours back.
I do this:
moment(value.Planet.when).local().format('YYYY-MM-DD HH:mm:ss')
and I get the same date time as the UTC. I don't understand how can I get momentjs to show the UTC time relative to the local time. I checked that the momentjs object is indeed UTC.
I thought that if I pass the moment.utc() function the UTC date that I've got from the webservice (originally from the database), I can just run the local() function and I'll get the accurate hour relative to my area, but it didn't work.
You can use moment(date).format('YYYY-MM-DDTHH:mm:ss');
Eg:- if you date "/Date(1469271646000)/"
ip-> moment(1469271646000).format('YYYY-MM-DDTHH:mm:ss');
op-> "2016-07-23T16:30:46"
Do not use the _d property. It is for internal use only. See this answer, the user guide, or Maggie's blog post on the subject.
As far as you question of how to convert to local time, you don't actually need to convert at all. You're already parsing the input value in local mode, so you can just use it directly:
var m = moment("/Date(1469271646000)/"); // gives you a moment object in local mode.
var s = m.format(); // lets you format it as a string. Pass parameters if you like.
var d = m.toDate(); // gives you a Date object if you really need one
Try to avoid using Date objects unless they're required by some other controls or libraries you're using. Most operations can be done strictly on moment objects.