How to display Datetime considering offset using MomentJS with Timezones - javascript

I'm using moment.js with timezones to create a datetime belonging to a specific timezone:
var datetime = moment.tz("2016-08-16 21:51:28","Europe/London");
Because this constructor is aware of DST (daylight saving time), moment.js will add +1 hour offset automatically. datetime.format() will show: 2016-08-16T21:51:28+01:00.
But it seems when printing the date, the offset ins't considered. E.g. datetime.format('DD.MM.YYYY - HH:mm:ss') will show: 16.08.2016 - 21:51:28 but I wan't it to show: 16.08.2016 - 22:51:28 (the time considering the DST-Offset of 1 hour). Does anyone know how to do this?

You are misinterpreting the output you're getting.
When you see +01:00 at the end of an ISO8601 timestamp, it doesn't mean that you need to add an hour. It means that timestamp given is in a local time zone that is one hour ahead of UTC at that point in time. Moment isn't adding an hour. It's simply reflecting the local time in London.
For the timestamps you provided, showing 22:51:28 would be an error. The local time in London is 21:51:28, and the equivalent UTC time is 20:51:28. You wouldn't find 22:51:28 until you went one time zone to the East, at UTC+2.
Now, if what you meant to do is convert from UTC to London time, then you need to create the input as UTC and then convert.
moment.utc("2016-08-16 21:51:28").tz("Europe/London")
Then you'd get 22:51:28 when formatting, which is the result you asked for, but this is a different point in time.

Related

Simplest way to find out how many milliseconds until a specific time in a specific timezone (taking DST into account)?

I have a piece of code which finds the difference between two dates(in the format of yyyy-MM-dd hh:mm:ss) . This code is run in multiple servers across the globe. One of the two dates is the current time in that particular timezone where the code is being run(server time) and another is the time obtained from a database. if the difference between these two times is greater than 86400 seconds(1day), then it should print "invalid" else, it should print "valid".
Problem im facing with the code is when I run it on my local, its working fine, but when i deploy it onto a server in US, its taking GMT time into consideration and not local time.
Wherever the code is run, I want the difference between current time and time fetched from the database, and if its greater than 86400 seconds, i want to print invalid. How to achieve this in java?
PS: I tried with Date object, but its considering GMT only everywhere.
I would use GMT everywhere and only convert to the local times for display purposes.
To find the difference, convert both times to the same timezone (say GMT) and take the difference.
You can do it by the below example code.
Date date = new Date();
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));
Date date1 = dateformat.parse(formatter.format(date));
// Set the formatter to use a different timezone
formatter.setTimeZone(TimeZone.getTimeZone("IST"));
Date date2 = dateformat.parse(formatter.format(date));
// Prints the date in the IST timezone
// System.out.println(formatter.format(date));
Now compare date1 with date2
First, I concur with Peter Lawrey's answer up there. It is usually good practice to store all time in the database for a single zone, and render it with offset for the user based upon the user's locale.
To find the difference, use the method getTime() to get the time in milliseconds from the epoch for each date. The calculation for the difference of 1 day is then 86400 * 1000 milliseconds. Or, perhaps, store the time in milliseconds from epoch in the database, and use a DB procedure/function at the time of retrieval.
Hope this helps.

Convert ISO/UTC date to local by displaying timezone javascript/momentjs

I have a date in the format like 2019-05-18T19:30:00-0400 which I need to display as 05/18/2019 07:30 PM EST using momentjs or plain javascript. I tried several ways, for example, moment(new Date('2019-05-18T19:30:00-0400')).format('MM-DD-YYYY h:mm A zz')
It is impossible to determine a time zone from an offset alone. There are many offsets that belong to more than one time zone. Thus rendering an abbreviation is impossible.
See Time Zone != Offset in the timezone tag wiki for further details, and refer to the list of tz database time zones if you would like examples.
However, from your comments it appears you that you would also like to keep the same local time and offset as you are given. Moment can help with that part, using its (inappropriately named) parseZone function:
moment.parseZone("2019-05-18T19:30:00+0100").format("MM/DD/YYYY hh:mm A ZZ")
//=> "05/18/2019 07:30 PM +0100"

Convert UTC Time To Local DST Time

I want to convert UTC time to local Time Zone where Time Zone will be dyanamic.
The question is asked because I want my UTC date to get converted automatically using DayLightSaving Time.
DayLightSaving for Adelaide on 2019-04-25 is +4 hours and standard is +5.
This +1 hour or -1 hour should be calculated automatically.
I hava gone through all stackoverflow similar questions but could not find or relate well. so how to convert UTC date into DST date ? momemt.js can be used but plz avoid giving links in your answer. I would prefer actual function to convert dates.
Here is the actual problem,
`Current Date = 2019-04-25 --yyyy-mm-dd
TimeZone = Adelaide
MyUTCDate = 2019-04-25 8:30:00
ConvertedDSTTime = ?`
It is unclear from your question, but perhaps you are looking for something like this?
new Date('2019-04-25T08:30:00Z').toLocaleString('en-AU', {timeZone: 'Australia/Adelaide'})
//=> "25/04/2019, 6:00:00 pm"

.tz() in moment.js timezone does not convert time zones correctly

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?

Moment.js local relative time

I have dates in my database set to Europe/London time. I am using Moment.js to show relative time e.g. "3 minutes ago". This works fine for me as I am in the same timezone, but for example, someone who is PST timezone would see "in 8 hours". How can I fix this?
My current code is like this:
$('time').text( moment( '2016-01-22 18:00:00' ).fromNow() );
To echo Jon's answer, moment's relative time functionality is strictly UTC based, so the behavior you describe won't actually happen, unless you are interpreting the original timestamp in local time.
It's hard to say if you're doing that or not, as you didn't give a sample value of the input string.
If your times are indeed UTC based, but that's not reflected in the input string, then use moment.utc instead of just moment.
And no, London is not the same as UTC.
I believe that the best approach is to store the date in UTC and then convert this to the local time zone for display. Note that this is not necessarily the same as London time because UTC does away with daylight savings time nonsense. You can do everything that you need with the date class provided the time stamp stored in the database does not have to deal with the vagaries of time zone and DST. The date class maintains its own epoch internally as milliseconds elapsed since midnight 1 January 1970 UTC. You can evaluate the difference between two Date objects as follows:
var agora = Date.now();
var stored = ... // the date that was stored in your database
var diff_msec = agora.getTime() - stored.getTime();
Knowing that the difference and that its units are milliseconds, you can convert the difference to whatever units are best for presentation.

Categories