How do I calculate hours from PM to AM using moment.js? - javascript

I've been working on calculating the total hours, minutes and seconds between two times using the moment.js library. The problem I have is that the calculations don't recognise that it's a day and return more hours than what is there. I'll give you an example:
I want to know how many hours are between 21:00 and 06:00, the answer is 9, however, the calculation brings back -15, this is also technically correct. I need to tell moment that it should use a day to calculate this value. I can get it to work if I use a DateTime picker but I don't want to use that as the user is only required to provide a time.
My application uses KendoUI for MVC and moment.js, moment.duration.format.js and moment.range.js
Here is my code which will return -15
#(Html.Kendo().TimePicker().Name("start").Value("21:00"))
#(Html.Kendo().TimePicker().Name("end").Value("06:00"))
<button class="btn btn-default btn-success" onclick="calc()">Plot</button>
Here is the javascript that works with this.
function calc() {
window['moment-range'].extendMoment(moment);
console.clear();
var dformat = "HH:mm:ss";
var start = $("#start").data("kendoTimePicker").value();
var end = $("#end").data("kendoTimePicker").value();
var startTime = moment(kendo.toString(start));
var endTime = moment(kendo.toString(end));
var duration = moment.duration(endTime.diff(startTime));
var hours = parseInt(duration.asHours());
console.log(hours);
}
If we change this to use DateTimePicker instead, it understands there is a day and calculates 9 hours. So how do I get around this? How can I achive this without using a datetime picker? Can I leaverage moment.js startof day or something?

Thanks to #VincenzoC I have managed to fix this problem. Here is the code which checks if the end time is before the start time and if it is, add a single day. This means the resulting time is accurate.
var startTime = moment(start);
var endTime = moment(end);
if (endTime.isBefore(startTime))
{
endTime.add(1, 'd');
}
//
//After the above condition has been passed, calculate the difference
var duration = moment.duration(endTime.diff(startTime));
//
//Any format you want
console.log(duration.format("HH"))

Related

Attempting to get momentjs to calculate difference in times

I am trying to setup a interval to run every morning at 0730. I am trying to use momentjs to accomplish this.
e.g:
current time - 0730 = how long to wait until it is time to run the function.
For some reason no matter how I manipulate the moment it seems to come back with some wonky math. For example it is currently 0616 in the morning and when I attempted to get this to do the math it came back with a 6hr difference not just over an hour.
var endOfShift = moment('0730', 'HHmm').format(),
now = moment().utcOffset(-8).format(),
diff = moment(now).local() - moment(endOfShift).local();
console.log(endOfShift); // => 2019-12-20T07:30:00+00:00
console.log(now); // => 2019-12-20T06:11:38-08:00
console.log(diff); // => 24098000 milliseconds = 6.6938888889hrs
I have tried removing the utcOffset from now which then the out put for the time/date incorrect. I have tried adding utcOffset to the endOfShift variable. No matter how I mess with the utc it still seems to = around 6hrs when it should be about 1ish. I have tried just removing the utcOffset from everything and just let it do its thing and it still gets the math wrong.
I have also tried moment's diff method w/ similar results.
What am I missing?
-Adam
I think you can achieve this with something like this
const now = moment();
let targetTime = moment('07:30', 'hh:mm'); // could be in past or in future
if (targetTime.isBefore(now)) {
targetTime = targetTime.add(1, 'day'); // add one day if waiting for tomorrows time
}
const diff = targetTime.diff(now);
console.log(diff);
const otherDiff = targetTime - now;
console.log(otherDiff);
The values for diff and otherDiff should be equal so it's up to you which one you prefer.

Moment JS duration shows wrong time?

Im trying to convert duration in seconds to human friendly output using moment js and combination of duration and format.
Im getting the duration in seconds and then formatting it like so:
const value = 337650
const duration = (durationSeconds) => {
const duration = moment.duration(durationSeconds, 'seconds')
return moment.utc(duration.asMilliseconds()).format('D [days] HH:mm:ss')
}
console.log(`Duration: ${duration(value)}`)
outputs
"Duration: 4 days 21:47:30"
JSBin here
The problem I have is that it seems wrong. Online services like https://www.tools4noobs.com/online_tools/seconds_to_hh_mm_ss/ shows one day less.
Im not sure what library/algorithm these services are using and if they are showing the correct time elapsed or moment js.
Any ideas greatly appreciated!
You seem to be converting the duration into an epoch time, then formatting it, which will be wrong.
Take a look at this Moment issue for details about duration formatting. https://github.com/moment/moment/issues/1048
Simple formatting can be done using the humanize method:
let value = 337650
let duration = moment.duration(value, 'seconds')
duration = duration.humanize()
console.log(duration)
"4 days"
Fore more sophisticated formatting you may want to dive into: https://github.com/jsmreese/moment-duration-format.
try something simple:
var x = 337650%86400;
var days = (337650 - x)/86400;
var y = x%3600;
var hours= (x-y)/3600;
var sec = y%60;
var mins=(y-sec)/60;
alert(days + ' days ' + hours+':'+mins+':'+sec)
You can use the moment-duration-format plugin to format durations, the previous approach (creating a new absolute date from a duration) is not going to work. When you add 337650 seconds to the Unix Epoch start, you get January 4, 1970, 21:47:30, which is why you're seeing the day as 4.
As a further example of how this will go badly wrong, imagine we need to format a duration of, say, 2700000 seconds. This will give us an output of "1 days 06:00:00". Why? Because it's equivalent to February 1 1970, 06:00. (The real result will be 31 days, 06:00:00).
I don't think we can blame the authors of moment.js (they've done an amazing job), it's just not using the format function on moment.js as it is supposed to be used.
By using the format function from moment-duration-format, we're formatting as a duration rather than as an absolute time and we get the right result!
momentDurationFormatSetup(moment);
const value = 337650
const duration = (durationSeconds) => {
const duration = moment.duration(durationSeconds, 'seconds')
return duration.format('D [days] HH:mm:ss');
}
console.log(`Duration: ${duration(value)}`)
document.getElementById('output').innerHTML = `Duration: ${duration(value)}`;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.2.2/moment-duration-format.min.js"></script>
<div id="output">
</div>
JSFiddle: https://jsfiddle.net/t07ez8o4/9/

A set ISO8601 time to now-time

I am trying to display sort of a "time since" counter on my website. The API call outputs like this.
"created_at": "2018-05-16T14:00:00Z",
How would I go toward displaying the time since this time? This time is always set UTC time zone.
Preferably in a hh:mm format.
Appreciate all help.
This is very simple
var create_at = new Date("2018-05-16T14:00:00Z");
var current_time = new Date();
var elapsed_time = current_time - create_at;
elapsed_time is the time since create time in milliseconds. You can get seconds dividing it by 1000 like this.
var elapsed_seconds = elapsed_time / 1000;

Finding number of days between two dates in javascript/redux

let oneDay = 24*60*60*1000;
let firstDate = new Date();
let secondDate = this.props.eventData.date
let finalSecDate = new Date(secondDate)
var timeDiff = Math.abs(firstDate.getTime() - finalSecDate.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
I am trying to calculate the number of days between two dates using javascript in a redux project. (My second date variable above is based on the date that a user enters and then I am changing it into a new Date format.) The above code works but when the event has passed the the number of days until the event is still coming up as positive number of days. Can someone please help me distinguish whether or not the date has passed so I can get the negative number of days.
I appreciate any help you can give, thank you !
I would recommend using Moment.js, since they have a number of date functions that will become useful as you play around with dates more.
Here's what it would look like if you wanted to find the difference between two dates:
var present = moment();
var end = this.props.eventData.date;
present.diff(end, 'days') // 5
The diff function finds the difference between the two dates. It also solves your problem of returning a negative value if the date already passed.
var present = moment();
var past = moment('2014-02-03 12:53:12');
past.diff(present, 'days') // -1379

calculate minutes from starting and ending time

I am trying to calculate how many minutes a worker works from the input starting and ending time(e.g. 10:30 am to 3:30pm). Could u guys help how to calculate them? Could u check my code and correct them? I am very new in Javascript.
function myFunction(){
var sTime=document.getElementById("startTime").value;
var eTime=document.getElementById("endTime").value;
var diff = sTime-eTime;
var result= diff.getMinutes();
document.getElementById("demo").innerHTML=result`;
https://jsbin.com/bolapox/edit?html,output
You will need to turn the users input into a usable format with Date().parse(input). This returns the number of milliseconds since 1 January, 1970, 00:00:00, local time.
You can then take the difference in milliseconds and convert them into minutes.
var sTime=Date().parse(document.getElementById("startTime").value);
var eTime=Date().parse(document.getElementById("endTime").value);
var diff = eTime - sTime;
var result = diff / 60000;
You should consider Moment.js, here yiou can find some examples:
http://momentjs.com/docs/#/durations/

Categories