Only want to compare TIME values MomentJS - javascript

After looking through some of the other MomentJS Questions and answers I'm still stumped as to how one would use moment to simply compare two different times.
I do not need (want) the day/date to be considered.
My use case is this:
I'm reading a schedule (start/end times) from a config file. This is done using Node.js
Starttime = 6:30 PM
Endtime = 3:30 AM
var currentTime= moment(); // e.g. 11:00 pm
var starttime = moment('06:30 pm', "HH:mm a");
var endtime = moment('03:30 am', "HH:mm a");
amIBetween = currtime.isBetween(starttime , endtime);
console.log(amIBetween); // returns false
My scenario is technically spanning two days and I understand why it's false.
I need (expect) moment to return TRUE - i.e. that currtime isBeteen start and endtime and falls in that range.
Would I need to check for a time after 12AM and then add a day to make the check work?
Any other suggestions for accomplishing this. I looked at moment-range which has 'contains ' function but with similar question for that.
I'm finding it hard to believe that it's this complex, but maybe it is :\
--
Here's further clarification that issue arises with spanning days, even when trying to be more explicit:
var currentTime= moment('11:00p', "HH:mm a");
var startTime = moment('06:00p', "HH:mm a");
var endTime = moment('03:30a', "HH:mm a");
currentTime.toString(); //"Fri Oct 28 2016 23:00:00 GMT-0400"
startTime.toString(); // "Fri Oct 28 2016 18:00:00 GMT-0400"
endTime.toString(); // "Fri Oct 28 2016 03:30:00 GMT-0400"
currentTime.isBetween(startTime, endTime); // false
currentTime.isAfter(endTime) && currentTime.isBefore(startTime); //false
currentTime.isAfter(startTime) && currentTime.isBefore(endTime); //false
Seems kind of obvious that they'd be false since the day/date is considered by moment. This is what I'm trying to get around.
The following would work:
endTime.add(1, "days");
currentTime.isBetween(startTime, endTime); // TRUE
This would mean however, that I'd need to check if the START TIME was before 12AM && the ENDTIME as after 12AM then add 1 day to ENDTIME. Kludge?

After my own testing and looking at other's suggestions it sill appeared that disregarding DAY/DATE and trying to span days was an issue. I came up with this which is now working in my app.
isTimeBetween = function(aStartTime, anEndTime, aCurrTime)
{
// you may pass in aCurrTime or use the *actual* current time
var currentTime = !aCurrTime ? moment() : moment(aCurrTime, "HH:mm a");
var startTime = moment(aStartTime, "HH:mm a");
var endTime = moment(anEndTime, "HH:mm a");
if (startTime.hour() >=12 && endTime.hour() <=12 )
{
endTime.add(1, "days"); // handle spanning days
}
var isBetween = currentTime.isBetween(startTime, endTime);
/*** testing
startTimeString = startTime.toString();
endTimeString = endTime.toString();
currentTimeString = currentTime.toString();
console.log(startTimeString);
console.log(endTimeString);
console.log(currentTimeString);
console.log('\nis '+ currentTimeString + ' between ' +
startTimeString + ' and ' + endTimeString + ' : '
+ isBetween);
****/
return isBetween;
}
isTimeBetween("06:30pm", "03:30am", "11:00pm"); //true !! this is main use case
isTimeBetween("06:30pm", "10:30pm", "11:00pm"); //false
isTimeBetween("04:00am", "06:00am"); //true (e.g. current time is 5am

I see two issues.
1) Your variable name currtime on line 5 is different than your declaration on line 1 currentTime
2) You could break it up into two checks around midnight like so:
var currentTime = moment(); // e.g. 11:00 pm
var sixThirty = moment('06:30 pm', "HH:mm a");
var midnight = moment('12:00 am', "HH:mm a");
var threeThirty = moment('03:30 am', "HH:mm a");
amIBetween1 = currentTime.isBetween(sixThirty , midnight);
amIBetween2 = currentTime.isBetween(midnight , threeThirty);
console.log(amIBetween1);
console.log(amIBetween2);

dylpickle's answer looks correct to me, but if you decide that the isBetween is easy to fumble, then you may want to take that abstraction away, take a step down into it's functionality.
"explicitness is far cheaper than the wrong abstraction"
That is not to say that isBetween is the wrong abstraction, but it is a tiny bit less explicit in that you could easily feed it the parameters in the wrong answer which would give you the opposite of what you intended.
If you
console.log(currentTime.isBetween)
you get the implementation:
ob(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}
Notice that it just uses isAfter() and isBefore().
Sometimes you can simplify things sometimes by being more explicit with your code.
isBetween looks a little uglified and seems to cover all of the edge cases, but don't be afraid to try to improve things either.
Try the following code:
const isBetween = currentTime.isAfter(endtime) && currentTime.isBefore(starttime);
console.log(isBetween)
There is no way to get confused in the implementation or adding changes later. This does not increase cyclomatic complexity or lines of code.

I was facing the same issue and I did a kind of work around as follows:
function fgEsHora1MayorAHora2(hora1, hora2) {
var f1 = moment('2000-01-01 ' + hora1);
f1.tz('America/Mexico_City').format('ha z');
let f1Hora = f1.toObject().hours;
let f1Minutos = f1.toObject().minutes;
var f2 = moment('2000-01-01 ' + hora2);
f2.tz('America/Mexico_City').format('ha z');
let f2Hora = f2.toObject().hours;
let f2Minutos = f2.toObject().minutes;
let minutos1 = parseInt(f1Hora * 100) + parseInt(f1Minutos);
let minutos2 = parseInt(f2Hora * 100) + parseInt(f2Minutos);
return minutos1 > minutos2;
}
I separated the hours and multiply it by 100 in order to give it more value... so, I added "hours" plus minutes and then I did the comparison..
Remarks: The trick stands on add the date like "2001-01-01", just to be able to get the time and hour...
And it's working fine!!

Related

Javascript moment - timezone, difference between dates in different time zones

I have:
var now = moment.format(); //get current time
var days = 5; //days I need to subtract from time(then)
var then = '05/02/2016 12:00 am';
Now I need to get difference between now and then substract(-) 5 days but in +0000 so GMT +0.
so now must be in user localtime and then must be at +0000 GMT.
How I can get difference between this dates in days, hours, minutes, seconds?
I try:
var now = moment().format();
var then = moment('05/02/2016 12:00 am').utcOffset(+0000).format();
then = moment(then).subtract(5,'days');
d = moment.utc(moment(now).diff(moment(then))).format("DD HH:mm:ss");
but I get result- which is wrong...
"27 18:48:55"
The problem is that you're trying to use a time difference as a time. You need to use moment.duration() with the return value of the diff. You should also call then.diff(now) to get a positive difference. There were also some unnecessary calls to .format() and moment() that I removed.
var now = moment();
var then = moment('05/02/2016 12:00 am').utcOffset(+0000).subtract(5, 'days');
var duration = moment.duration(then.diff(now));
console.log(duration.days(), duration.hours(), duration.minutes(), duration.seconds());
logs
4 3 15 46

Unix offset with fullCalendar difference

I want to place a check when I'm getting a momentjs instance through fullCalendar.
I'm at the eventRender callback
var calendar = $('#calendar').fullCalendar('getCalendar');
var atime = calendar.moment();
var atime_h = atime.format("HH:mm");
atime = atime.unix();
var start = calendar.moment(event.start);
var start_u = start.unix();
var start_h = start.format("HH:mm");
console.log(atime);
console.log(atime_h);
console.log(start_u);
console.log(start_h);
Now what that logs is this:
1408024477
15:54
1407888000
00:00
1408024477 == Thu Aug 14 15:54:37 2014 == is correct
But 1407888000 == Wed Aug 13 02:00:00 2014, where I would expect 00:00 instead of 02:00
So there's a difference between the event .unix()/format.() and the moment I created.
Anyone got a clue what's going on?
Edit:
So what happens is that if I create two new moments: moment() and a moment().utc(), I get the same timestamp for both. But when I then display them, there is a difference of two hours.
The .utc one returns two hours in the past, the one without the correct one for me. The timestamp is not two hours back.
But with the event.start (which has _isUTC=true, the timestamp is two hours in the future (!), and it displays it correct when formatted.
So maybe I need to have my event.start to be not UTC and two hours back somehow?
Edit by request in comment, this is what I use now:
var start = calendar.moment(event.start);
console.log(start);
start_utc = new Date(start.year(), start.month(), start.date(), start.hour(), start.minute(), start.second());
var start = calendar.moment(start_utc);
console.log(start);
Try converting your event.start date to utc first, here's how to do it in vanilla js:
start_utc = new Date(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate(), start.getUTCHours(), start.getUTCMinutes(), start.getUTCSeconds());
Then you can call .unix() on it and it should give you the expected timestamp.

Javascript / Jquery - Calculate date and time

Given
departing date time 13/6/2014 01:00 AM
and
estimated landing time is 1 hour 50 minutes
i want the result like: 13/6/2014 2:50 AM
anyone have idea?
i have been using datejs with no luck
Here, take a look at moment.js (http://momentjs.com)
So let's say you have your starting time and duration set up like this:
var departTime = '13/06/2014 01:00 AM';
var duration = '1 hour 50 minutes';
First you need to convert the depart time to a moment object and parse the duration, like so:
var departTimeObj = moment(departTime, 'MM/DD/YYYY hh:mm A');
var durationParts = duration.split(' ');
var durationHours = durationParts[0];
var durationMinutes = durationParts[2];
Now you can use moment to do the addition:
var landingTime = departTimeObj.add({
hours: durationHours,
minutes: durationMinutes
});
To format the output the way you want, do this:
var landingTimeStr = landingTime.format('MM/DD/YYYY hh:mm A');
Use the JavaScript date object.
var travelling = 110 // in minutes
var departing = new Date(2014, 6, 13, 1, 0, 0, 0);
var arriving = new Date(departing.getTime() + travelling * 60000);
Here's a fiddle.
Or use many of the libraries already out there.
As Matt Johnson says, you need to be weary of gotchas like daylight saving time if you're going to be adding variable units of time like days.

Comparing two times with Moment JS

I have a problem that requires me to take two times in 12 hour format and compare them, we have moment.js included in our project and we initially thought it would be as trivial as this:
var beginningTime = moment('8:45am');
var endTime = moment('9:00am');
console.log(beginningTime.isBefore(endTime)); //false???
Fiddle: http://jsfiddle.net/KyleMuir/M4R4z/
Is there something we are missing? It feels like this shouldn't be a hard problem to solve. When we perform any moment functions on our beginningTime or endTime it simply says NAN
If you are always dealing with the time in h:mma format, you can specify it when parsing...
var beginningTime = moment('8:45am', 'h:mma');
var endTime = moment('9:00am', 'h:mma');
console.log(beginningTime.isBefore(endTime)); // true
console.log(beginningTime.toDate()); // Mon May 12 2014 08:45:00
console.log(endTime.toDate()); // Mon May 12 2014 09:00:00
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>
It will use today as the date, so it won't work if you are spanning different days.
JSFiddle
As per documentation you are declaring moment variable incorrectly check allowed formates
http://momentjs.com/docs/#/parsing/string/
Instead of it you can use
var beginningTime = moment({
h: 8,
s: 45
});
var endTime = moment({
h: 9,
s: 0
});
console.log(beginningTime.isBefore(endTime)); //true
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>
8:45am and 9:00am are invalid dates
var beginningTime = moment('8:45am');
var endTime = moment('9:00am');
console.log(beginningTime.isValid(), endTime.isValid()) // FALSE
You should use a valid format: http://momentjs.com/docs/#/parsing/string/
And they suggest that for consistent results, should use http://momentjs.com/docs/#/parsing/string-format/
Eg.
moment("2010-10-20 4:30", "YYYY-MM-DD HH:mm"); // parsed as 4:30 local time
You should just open the console and try doing this manually: moment("8:45am").toDate()
It gives you Invalid Date, which is why you're not getting expected results. Whereas "2014-05-15 08:45" gives you a date.

Javascript convert seconds to a date object

How can I convert seconds into a datetime object in javascript.
Examples:
1.3308313703571
1.6324722385401
This is from a series of points and when they occurred. I understand 1.23323 more then seconds, but I can not change the value, being pulled from an api.
You can try like this:
function toDateTime(secs) {
var t = new Date(1970, 0, 1); // Epoch
t.setSeconds(secs);
return t;
}
Info on epoch date.
You can pass unix timestamp milliseconds as an argument to the Date constructor:
const secs = 30;
const output = new Date(secs * 1000);
console.log(output);
#UVM's answer is helpful, but slightly incomplete if you're dealing with timezones (i.e. UTC vs local time). With timezones, start with UTC using Date.UTC and Date.setUTCSeconds to get a true UTC date and time.
function toDateTime(secs) {
var t = new Date(Date.UTC(1970, 0, 1)); // Epoch
t.setUTCSeconds(secs);
return t;
}
You can then use a library like Moment to convert/format it to a local timezone.
your example values have a decimal.. looking like you are trying to convert 1.something seconds into a date..
Meanwhile check this example here on the correct seconds to date conversion.. you could view their js sources.
The question seems to have already been answered but this may be helpful for those attempting to do something similar to ruby's Time.at() method.
function formatDateTime(input){
var epoch = new Date(0);
epoch.setSeconds(parseInt(input));
var date = epoch.toISOString();
date = date.replace('T', ' ');
return date.split('.')[0].split(' ')[0] + ' ' + epoch.toLocaleTimeString().split(' ')[0];
};
I dunno how it be 10 years ago, but now it can solve just doing next:
let sec = 1628618888939
let time = new Date(sec)
let normalDate = new Date(sec).toLocaleString('en-GB',{timeZone:'UTC'})
time: "Tue Aug 10 2021 21:08:08 GMT+0300 (Eastern European Summer Time)"
normalDate: "10/08/2021, 18:08:08"
If in the future u will have problems like this, I can advise read about functions that relate to your question, and solution will come.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString

Categories

Resources