Momentjs adding utcoffset without changing datetime - javascript

at the moment I am trying to add a utc offset to a date string such as "2023-01-17T06:00:00Z"
the desired result would be 2023-01-17T06:00:00+11:00
so far everything I do adds the +11:00 offset but changes the actual time as well for example
"2023-01-17T06:00:00Z" >> "2023-01-17T17:00:00+11:00"
instead I would want
"2023-01-17T06:00:00Z" >> "2023-01-17T06:00:00+11:00"
here is the code I've tried but hasn't worked.
moment(2023-01-17T06:00:00Z).tz(timeZone, true)
this still ends up adding the offset to the original datetime
i was wondering if anyone knew how to do this?
im using moment-timezone btw.

Related

When converting date, I get previous day

I want to convert a string into a date "as it is".
const date = "8/16/2019"
console.log(new Date(date))
However, I get:
As you can see I get the prevous day. I was thinking that it might be a timezone issue, even though there is no timezone that I am converting it from.
Any suggestions how to convert is as it is?
I appreciate you replies!
If your format is consistent, you could split on / and use Date.UTC. Creating your new Date from that would ensure it's UTC.
const date = "8/16/2019"
const [month,day,year] = date.split("/");
const utcDate = Date.UTC(year,month-1,day);
console.log(new Date(utcDate));
const date = "8/16/2019"
console.log(new Date(date).toLocaleString("en-US", {timeZone: "Asia/kolkata"}))
Note:- You need to add timezone
You can use toLocaleDateString
console.log(new Date("8/16/2019").toLocaleDateString('en-us', {timeZone: "Asia/Kolkata"}))
new Date("8/16/2019") will create a date object using your current timezone. Add a "Z" at the end if you want your date to be in UTC.
console.log(new Date("8/16/2019Z"))
EDIT
It appears that Firefox is not implementing the parsing of standard date format. Unfortunately until recently how exactly was a date parsed was completeley based on heuristics and intrinsically non portable.
Looking at Firefox bug tracker seems the issue has been discussed but the problem is still present (some toolkit just works around by replacing "Z" with "+00:00" before calling the parser).
The only way to be sure on every browser is to parse the string yourself and build the date from the fields. I didn't notice because I'm using chrome instead (in both chrome and Node works as expected).
EDIT 2
After more investigation seems the standard requires that:
If you use yyyy-mm-ddThh:mm:ssz then you get what ISO format for datetime defines it to be. Also the syntax described in the standard is not very precise and for example is not clear to me if the time zone can be present when no time is present (Chrome says yes, Firefox says no).
If you use another format then anything goes (so for example there is no string that is guaranteed to issue an invalid date response).
In other words new Date("8/16/2019") is not portable Javascript (with the meaning that you don't know what date / time / timezone you will get, if any). Either you parse yourself the date or you just live with what that version of that Javascript engine in that moment decides to give you.

Moment time difference won't use moment timezone but users computer time

I'm attempting to display a duration ticker for something. The start time is always in London time. It works perfectly for people in England/the same timezone, however when people in other time zones look at the duration it displays the wrong value (If you're in a timezone behind England => negative values/too small values, timezone ahead => value too large).
My solution to this was to use moment-timezone. I added the moment timezone data correctly I've attempted to use this timezone data (code simplified and separated into individual lines for easier readability):
let londonTimeNow = moment().tz('Europe/London'),
jobStartTime = moment(job.start, 'DD/MM/YYYY HH:mm:ss'),
diff = londonTimeNow.diff(jobStartTime);
duration = moment.duration(diff).format('HH:mm:ss', {trim: false});
I was hoping this would then get the current time in London and compare to the start time no matter where you are in the world. However, it seems the diff function converts the time to the user's computer time. I tried formatting the londonTimeNow to be a string, but then the diff function doesn't work.
Note, I've debugged and moment().tz() is working correctly, I've tried with other time zones and it gets the correct time in the zone specified.
Any ideas?
EDIT:
It seems I can get it working by manually setting the offset property of 'londonTimeNow' to 0. However this doesn't feel quite right to me. I'd prefer a solution that seems less like a hack.
You should specify the jobstart time in the same way you declare london time using the same timezone:
jobStartTime = moment.tz(jobStart, 'DD/MM/YYYY HH:mm:ss','Europe/London'),
This will set the job start time using the same timezone.
Could you add expected output or specify what you mean by 'diff converts the time'?
The result of diff is a duration and is not in any timezone.
Other than that, the problem seems to be in not using timezone for task start.
Try this:
let londonTimeNow = moment().tz('Europe/London'),
jobStartTime = moment(job.start, 'DD/MM/YYYY HH:mm:ss').tz('Europe/London'),
diff = londonTimeNow.diff(jobStartTime);
duration = moment.duration(diff).format('HH:mm:ss', {trim: false});

Convert hour to date time without adding +1

Hi im using moment js to convert this string 20:00 I tried:
var a = moment("20:00", "HH:mm")
console.log(a.format()) // 2016-09-08T20:00:00+01:00
the problem when I store in mongodb it become
2016-09-10T19:00:00.000Z
I want to store 2016-09-10T20:00:00.000Z
anyway can explain why please ?
When you say that you want to store 2016-09-10T20:00:00.000Z what you are saying is that you want to assume that your date and time is UTC.
To assume that the date you are parsing is a UTC value, use moment.utc
var a = moment.utc("20:00", "HH:mm")
console.log(a.format()) // 2016-09-08T20:00:00Z
Note that when you parse a time without a date, moment assumes the current date. This may not be the behavior that you want.
I'm also not sure if you want a UTC date (which is what you are saying), or a local date without an offset indicator. If you want a local date without an offset indicator, simply use a format without an offset:
moment.utc("20:00", "HH:mm").format('YYYY-MM-DDTHH:mm:ss.SSS')
"2016-09-08T20:00:00.000"
If you are dealing with local dates that do not have a time zone association, I recommend using moment.utc to parse, as this will ensure that the time does not get shifted to account for DST in the current time zone.
For more information about how to parse dates into the time zone or offset that you would like in moment, see my blog post on the subject.
This it how it should look:
var a = moment("20:00", "HH:mm")
console.log(a.utcOffset('+0000').format())
<script src="http://momentjs.com/downloads/moment.min.js"></script>
Doe, the problem is that you are using timezones when you create the date.
MomentJS uses your current timezone automatically.
Mongo however saves the time as it would be in another timezone.
Therefore, if you want the two strings to format the same way, you need to set the timezone.

Moment.js 2 different date strings when i parse using moment gives same value

I am parsing 2 different date strings
var d1 = '2014-02-01T00:00:00.000+0530'
var d2 = '2014-02-23T00:00:00.000+0530'
when i parse them using moment
alert(moment(d1, 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"').toDate());
alert(moment(d2, 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"').toDate());
both of them print Sat Feb 1 2014 xxxxx
what is wrong with it??
here is the link to the fiddle i created
jsfiddle
I think your moment formatting string is causing you the problem. If I remove this, the dates do not print as the same.
http://jsfiddle.net/K5ub8/7/
EDIT: The specific issue is you are using dd for day, instead of DD. http://momentjs.com/docs/#/parsing/string-format/
Here is your fiddle fixed:
http://jsfiddle.net/K5ub8/9/
However, I am not 100% sure about the fractional seconds, I believe it is SSS instead of fffffff but I would test this if you need to cater for fractional seconds.
I should mention that if you are converting it back into a JavaScript date object anyway with toDate(), then you don't really need the moment formatting parameter as the date will be formatted in JSON Date format.
I would question why you would want to generate a moment formatted date, and then convert it back to JavaScript, a normal practice might be to receive a date in JavaScript format, then create a moment object which you can use to perform calculations and display in a nice user friendly way.
Simple answer: your format was off a bit.
http://jsfiddle.net/K5ub8/8/
After tweaking the format to be 'YYYY-MM-DDTHH:mm:ss.SSSZZ' rather than 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"' it worked just fine. When you're trying to debug issues like this, it's always good to keep the format in a separate variable so you can use the same format that you're trying to parse out to display what you're getting. Had you done that, you would have noticed that 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"' was messed up due to it printing out 2014-01-Fr"T"11:32:03.fffffff"-08:00". Which obviously isn't quite right.

Using timezones with moment.js fromNow() or from()

I want to show users how long has been elapsed since they performed an action.
The date+time of the action happening is stored on the server, in the server's timezone. That's what's causing the trouble, since if the user's computer's timezone is 12 hours ahead of the server's timezone, then if the user adds something right now, moment.js will show '12 hours ago' as the output of fromNow() rather than just now.
To try to solve this, I'm trying the following method:
var actionTime = moment( action.timeStamp);//time of when user performed action
var serverTime = moment().zone('-07:00'); //current server time
console.debug( serverTime);//outputs Wed Sep 11 2013 15:19:51 GMT-0700
var timeAgo = serverTime.from( actionTime);
But despite of all this, timeAgo still shows the difference between the client's timezone and the server's timezone (i.e showing '12 hours ago' instead of 'now');
Anyone know how to fix this or what I'm doing wrong?
Ideally, you would want to pass a UTC timestamp from your server to the client. That doesn't mean you have to switch your whole server over to UTC, it just means that you would convert from the time in your database to UTC on the server before sending it over the web. Sure, it would be even better if you actually stored times in UTC, but you said you aren't in a position to make that sort of change right now. But let's just work off the assumption that you can't change anything at all on the server.
We'll also assume that your server is fixed to the UTC-07:00 offset. In real life, this would only be true for places like Arizona that don't follow daylight saving time. So if you are in Los Angeles and are in Pacific Time, then some of your data is based on UTC-07:00, but some of it is based on UTC-08:00. That requires a lot more work if you want to do it in JavaScript.
Let's also assume that the input is already a string in ISO8601 format. (If it's not, then let me know and I will adjust this code.)
var s = "2013-09-11 18:00:00"; // from action.timeStamp
var actionTime = moment(s + "-07:00", "YYYY-MM-DD HH:mm:ssZ");
var timeAgo = actionTime.fromNow();
The reason your other code didn't work is because in the first line, you are affected by the time zone of the browser. The zone setter in the second line just changes the zone for formatting, not changing the actual moment in time.
Also, when you dump a moment to the console for debugging, make sure you format it for output. Otherwise you are just looking at its internal property values, which may or may not make sense directly.
I have solved it in a different way, maybe this option was not possible back when the question was asked, but might be easier now.
I used moment-timezone.js (which requires moment.js 2.6.0+).
I set the default timezone to my server's timezone like this:
moment.tz.setDefault("America/New_York"); // "America/New_York" in my case
and then just use it normally. fromNow() will use the timezone in the client to calculate the time that has passed since that moment.
moment(myDatetime).fromNow();
i had the same issue and used the above comments to modify my code. I did the following to get it resolved:
transform(value: string) {
var time = moment(value).utc();
return moment(time, "YYYYMMDD").fromNow();
}
I was missing the .utc() to convert it before I applied the .fromNow()
Things to note this is being used within a Pipe for Ionic 3 and the above code is from the pipe logic.

Categories

Resources