get total sum of minutes between 2 fields - javascript

im trying to get the total minutes from this 2 fields but i keep getting the 60 minutes results but wont show more even when there is few hours in between.
sample
01:59 04:59 getting result 60 minutes
01:59 04:59 wanted result 299 minutes
$(document).ready(function () {
if ($('#duration').val() === '') {
updateDuration($('#start_time').val(), $('#end_time').val());
}
$('#start_time').on('change keyup', function () {
updateDuration($('#start_time').val(), $('#end_time').val());
});
$('#end_time').on('change keyup', function () {
updateDuration($('#start_time').val(), $('#end_time').val());
});
function updateDuration(startTime, endTime) {
var ms = moment(endTime, ' HH:mm:ss').diff(moment(startTime, 'HH:mm:ss')),
dt = moment.duration(ms),
h = Math.floor(dt.asHours()),
m = moment.utc(ms).format('mm');
$('#duration').val('' + m + ' minutes');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
<p>
<label for="start_time">Start Time</label>
<br>
<input id="start_time" name="start_time" type="text" value="00:00">
</p>
<p>
<label for="end_time">End Time</label>
<br>
<input id="end_time" name="end_time" type="text" value="15:53">
</p>
<p>
<label for="duration">Duration</label>
<br>
<input id="duration" name="duration" type="text">
</p>

Here's one way to do it without moment. Just convert everything to seconds and subtract. If the endtime is less than the start time, we add 24 hours to the end.
$(document).ready(function() {
$('#start_time, #end_time').on('keyup', function() {
updateDuration($('#start_time').val(), $('#end_time').val());
});
$('#start_time').trigger('keyup')
});
const getSeconds = t => t.split(":").reduce((b, a, i) => b + (+a * (i === 0 ? 60 : 1)),0);
function updateDuration(startTime, endTime) {
let start = getSeconds(startTime),
end = getSeconds(endTime)
if (end < start) end += (24 * 60 )
let result = end - start
let m = Math.floor(result/60), s = Math.floor((result%60))
$('#duration').val(`${m} minutes, ${s} seconds`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
<p>
<label for="start_time">Start Time</label>
<br>
<input id="start_time" name="start_time" type="text" value="23:59">
</p>
<p>
<label for="end_time">End Time</label>
<br>
<input id="end_time" name="end_time" type="text" value="15:53">
</p>
<p>
<label for="duration">Duration</label>
<br>
<input id="duration" name="duration" type="text">
</p>

Related

Changes in time picker should also changes the time input field

I've got this code to show the total minutes in an input field. I would like to have changes in it whenever a user picks a different time in the time picker and the time in the input field also changes. How would I get that goal? This is the code I used:
const getSeconds = s => s.split(":").reduce((acc, curr) => acc * 60 + +curr, 0);
var seconds1 = getSeconds(document.getElementById("stime").value);
var seconds2 = getSeconds(document.getElementById("etime").value);
var res = Math.abs(seconds2 - seconds1);
var hours = Math.floor(res / 3600);
var minutes = Math.floor(res % 3600 / 60);
var seconds = res % 60;
document.getElementById("time").value = seconds;
<div>
<div class="form-floating">
<input id="stime" class="form-control" required name="stime" type="time" value="12:00" />
<label for="stime">Start Time</label>
</div>
</div>
<div>
<div class="form-floating">
<input id="etime" class="form-control" required name="etime" type="time" value="12:30" />
<label for="etime">End Time</label>
</div>
</div>
<div>
<div class="form-floating">
<input id="time" class="form-control" name="time" type="text" />
<label for="time">Time</label>
</div>
</div>
This is how image looks like...
The best practice is to move the calculation parts of your code into a function and call that function once the page is loaded and when any change is made to the inputs.
const getSeconds = s => s.split(":").reduce((acc, curr) => acc * 60 + +curr, 0);
const twoDigit = s => s < 10 ? '0'+s : s;
const timeToMins = s => s.split(':')[0]*60 + +s.split(':')[1];
const formatTime = s => {
let hours = Math.floor(s / 60);
let minutes = Math.floor(s % 60);
return `${twoDigit(hours)}:${twoDigit(minutes)}`
}
const updateInput = () => {
let start = getSeconds(document.getElementById("stime").value);
let end = getSeconds(document.getElementById("etime").value);
let res = Math.abs(end - start);
let diff = formatTime(res)
document.getElementById("time").value = diff;
}
const updateEnd = () => {
let start = getSeconds(document.getElementById("stime").value);
let diff = document.getElementById("time").value
let end = formatTime(start+timeToMins(diff))
document.getElementById("etime").value = end;
}
updateInput()
<div>
<div class="form-floating">
<input id="stime" onchange="updateInput()" class="form-control" required name="stime" type="time" value="12:00" />
<label for="stime">Start Time</label>
</div>
</div>
<div>
<div class="form-floating">
<input id="etime" onchange="updateInput()" class="form-control" required name="etime" type="time" value="12:30" />
<label for="etime">End Time</label>
</div>
</div>
<div>
<div class="form-floating">
<input id="time" onkeyup="updateEnd()" class="form-control" name="time" type="text" />
<label for="time">Time Difference</label>
</div>
</div>
These are the codes I have so far for this.
const getSeconds = s => s.split(":").reduce((acc, curr) => acc * 60 + +curr, 0);
var seconds1 = getSeconds(document.getElementById("stime").value);
var seconds2 = getSeconds(document.getElementById("etime").value);
var res = Math.abs(seconds2 - seconds1);
var hours = Math.floor(res / 3600);
var minutes = Math.floor(res % 3600 / 60);
var seconds = res % 60;
document.getElementById("time").value = seconds;
<div>
<div class="form-floating">
<input id="stime" class="form-control" required name="stime" type="time" value="12:00" />
<label for="stime">Start Time</label>
</div>
</div>
<div>
<div class="form-floating">
<input id="etime" class="form-control" required name="etime" type="time" value="12:30" />
<label for="etime">End Time</label>
</div>
</div>
<div>
<div class="form-floating">
<input id="time" class="form-control" name="time" type="text" />
<label for="time">Time</label>
</div>
</div>

How do I get the number of days from 2 user inputs and then multiply it with another user input which is amount in JavaScript?

I'm trying to create a simple fine calculator, I have two user input dates and a user input amount.
I need to subtract the 2 dates and then multiply the number of days by the fine amount. I went through a bunch of videos about dates, but none of them ever take user input. I am very new to javascript so I don't know why it won't show me my result. Could someone tell me what's wrong with my code?
if (isset($_POST['calcDiff'])) {
$("#bdate").datetimepicker({
timepicker: false,
format: 'y-m-d'
});
$("#rdate").datetimepicker({
timepicker: false,
format: 'y-m-d'
});
function calcDiff() {
var bdate = new Date($("#bdate").val());
var rdate = new Date($("#rdate").val());
var amount = $('#amount').val();
var timeDifference = rdate.getTime() - bdate.getTime();
var milliSecondsInOneSecond = 1000;
var secondInOneHour = 3600;
var hourInOneDay = 24;
var daysDiff = timeDifference / (milliSecondsInOneSecond * secondInOneHour * hourInOneDay);
var fine = daysDiff * amount.val();
alert(fine);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="finecalc" action="" method="post">
<p>
Borrowed date
<input type="date" name="bdate" id="bdate" required="required" value="<?php echo $bdate; ?>" />
</p>
<p>
Return date</b>
<input type="date" name="rdate" id="rdate" required="required" value="<?php echo $rdate; ?>" /> <b>
</p>
<p>Enter fine amount per day</b>
<input type="text" name="amount" size="10"><b>
</p><button onclick="calcDiff()">Calculate Fine</button><p id="display"></p>
</form>
You can get the value from each input, then actually just subtract the dates to get the epoch difference and with that number you can convert it to days and multiply by the fine.
I added a JS that does just that.
function calcDiff(){
const date1 = new Date(document.querySelector('#bdate').value);
const date2 = new Date(document.querySelector('#rdate').value);
const penalty = document.querySelector('input[name="amount"]').value;
const diff_ms = date2 - date1;
// ms -> s -> min -> h -> days
const days = diff_ms / 1000 / 60 / 60 / 24;
const amount_to_pay = days * penalty;
console.log('$' + amount_to_pay);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="finecalc" action="" method="post">
<p>
Borrowed date
<input type="date" name="bdate" id="bdate" required="required" value="<?php echo $bdate; ?>" />
</p>
<p>
Return date</b>
<input type="date" name="rdate" id="rdate" required="required" value="<?php echo $rdate; ?>" /> <b>
</p>
<p>Enter fine amount per day</b>
<input type="text" name="amount" size="10"><b>
</p><button type="button" onclick="calcDiff()">Calculate Fine</button><p id="display"></p>
</form>
var amount = $('#amount').val();
...
var fine = daysDiff * amount.val();
Maybe no need to use amount.val()?
var fine = daysDiff * amount;
Also, remove the comma in this line:
var daysDiff = timeDifference / (, milliSecondsInOneSecond * secondInOneHour * hourInOneDay);
First you need to calculate difference between 2 dates and total number of days
const date1 = new Date('7/13/2010');
const date2 = new Date('12/15/2010');
const diffTime = Math.abs(date2 - date1);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); // calculate number of days
console.log(diffDays + " days");
var amount = $('#amount').val(); //store Amount value into amount variable
Then calculate fine:
var fine = daysDiff * amount;
This is what wound up working for me, thank you to all that helped.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="enterbooks.css" />
</head>
<body style="background: url(library.png); background-size: 100%;">
<div class="content">
<h1>Hey admin calulate you fines here!</h1>
<script>
function calcDiff() {
const date1 = new Date(document.querySelector('#bdate').value);
const date2 = new Date(document.querySelector('#rdate').value);
const penalty = document.querySelector('input[name="amount"]').value;
const diff_ms = date2 - date1;
// ms -> s -> min -> h -> days
const days = diff_ms / 1000 / 60 / 60 / 24;
const amount_to_pay = days * penalty;
alert(amount_to_pay);
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="finecalc" action="" method="post">
<p>
Borrowed date
<input type="date" id="bdate" required="required" value="<?php echo $bdate; ?>" />
</p>
<p>
Return date</b>
<input type="date" id="rdate" required="required" value="<?php echo $rdate; ?>" /> <b>
</p>
<p>Enter fine amount per day</b>
<input type="text" name="amount" size="10"><b>
</p><button type="button" onclick="calcDiff()">Calculate Fine</button>
<p id="display"></p>
</form>
</div>
</body>
</html>

Doing math with input type="time"

I'm trying to do a time calculator using the input type="time" value, but getting NaN as a result. Here's my code:
document.getElementById("MathButton").onclick = timeCalc;
function timeCalc() {
let startTime = document.getElementById("startTime").value;
let endTime = document.getElementById("endTime").value;
let diff = endTime - startTime;
document.getElementById("diff").innerHTML = (diff);
console.log(diff);
console.log(startTime, endTime);
<div>
<p>START</p>
<input type="time" id="startTime" name="start" value="08:00"><br />
<p>END</p>
<input type="time" id="endTime" name="end" value="16:30">
<br />
<button id="MathButton">Calculate!</button>
<br />
<p>Total: <br /> <span id="diff"></span> hours.</p>
</div>
I just can't get it to do the math, but I can see that both values are present if I add startTime and endTime to the console log.
**I accepted Doan's answer as correct as it is the least amount of code and gets the job done. I was able to understand that he took my times and made them into date objects, but since I am relatively new to this I was hoping for more of an explanation. Was able to figure it out though, and get my next part of the program built using this knowledge.
Subtracting two strings will result into NaN. Here, I have converted both the strings to date first and then subtracted it. Since substracting two dates gives the result in millisecond, result/ 60 /60 /1000 converts it to hours.
document.getElementById("MathButton").onclick = timeCalc;
function timeCalc() {
let startTime = new Date().toDateString("yyyy-MM-dd") + " " + document.getElementById("startTime").value;
let endTime = new Date().toDateString("yyyy-MM-dd") + " " + document.getElementById("endTime").value;
let diff = (new Date(endTime) - new Date(startTime)) / 60/ 60 / 1000;
document.getElementById("diff").innerHTML = (diff);
console.log(diff);
}
<div>
<p>START</p>
<input type="time" id="startTime" name="start" value="08:00"><br />
<p>END</p>
<input type="time" id="endTime" name="end" value="16:30">
<br />
<button id="MathButton">Calculate!</button>
<br />
<p>Total: <br /> <span id="diff"></span> hours.</p>
</div>
Here you go
document.getElementById("MathButton").onclick = timeCalc;
function timeCalc() {
let startTime = document.getElementById("startTime").value;
let endTime = document.getElementById("endTime").value;
//create date format
var timeStart = new Date("01/01/2007 " + startTime );
var timeEnd = new Date("01/01/2007 " + endTime );
var diff= timeEnd - timeStart;
diff= diff/ 60 / 60 / 1000;
document.getElementById("diff").innerHTML = (diff);
}
<div>
<p>START</p>
<input type="time" id="startTime" name="start" value="08:00"><br />
<p>END</p>
<input type="time" id="endTime" name="end" value="16:30">
<br />
<button id="MathButton">Calculate!</button>
<br />
<p>Total: <br /> <span id="diff"></span> hours.</p>
</div>
You can't just subtract two string first you have to convert them to integers to apply mathematical operations to them. Just split them by ':' like-
startTime.split(":")
endTime.split(":")
diff = toString(startTime[0]- startTime[0])+":"+toString(startTime[1]-
startTime[1])
this will form a list then excess the elements by index to subtract them startTime[0] for hours and so on

Adding Military Time - Textbox for HH and Texbox for MM?

I've been able to get this working GREAT when using a single textbox that has the HH:MM split with :, but when the HH are in a separate textbox from MM I'm completely lost. I'm needing to calculate time worked from the time entered and then outputted to the decimal format then minus the lunch. Any help would be awesome!
// adding military time
$(function () {
function calculate () {
var time1 = $("#element_33_1").val(), time1_1 = $("#element_33_2").val(), time2 = $("#element_34_1").val(), time2_1 = $("#element_34_2").val();
var hours1 = (time1),
hours2 = (time2),
mins1 = (time1_1),
mins2 = (time2_1);
var hours = hours2 - hours1, mins = 0;
if(hours <= 0) hours = 0 + hours;
if(mins2 >= mins1) {
mins = mins2 - mins1;
}
else {
mins = (mins2 + 60) - mins1;
hours--;
}
mins = mins / 60; // take percentage in 60
hours += mins;
hours = hours.toFixed(2);
$("#element_509").val(hours);
}
$("#element_33_1,#element_33_2,#element_34_1,#element_34_2").keyup(calculate);
calculate();
});
//Hours Billed Total
$(document).ready(function() {
$("#element_29,#element_509,#element_33_1,#element_33_2,#element_34_1,#element_34_2,#element_39").keyup(function(ev){
var val1=parseFloat($("#element_509").val());
var val2=parseFloat($("#element_39").val());
$("#element_29").val((val1 - val2).toFixed(2));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="li_33" class="time_field column_4">
<fieldset>
<legend style="display: none">Start Time</legend>
<span class="description">Start Time <span id="required_33" class="required">*</span></span>
<span>
<input id="element_33_1" name="element_33_1" class="element text " size="2" type="text" maxlength="2" value="" />
<label for="element_33_1">HH</label>
</span>
<span>
<input id="element_33_2" name="element_33_2" class="element text " size="2" type="text" maxlength="2" value="" />
<label for="element_33_2">MM</label>
</span>
</fieldset>
</li> <li id="li_39" class="column_4 guidelines_bottom">
<label class="description" for="element_39">Lunch Hour <span id="required_39" class="required">*</span></label>
<div>
<input id="element_39" name="element_39" class="element text medium" type="text" value="" />
</div>
</li> <li id="li_34" class="time_field column_4">
<fieldset>
<legend style="display: none">Stop Time</legend>
<span class="description">Stop Time <span id="required_34" class="required">*</span></span>
<span>
<input id="element_34_1" name="element_34_1" class="element text " size="2" type="text" maxlength="2" value="" />
<label for="element_34_1">HH</label>
</span>
<span>
<input id="element_34_2" name="element_34_2" class="element text " size="2" type="text" maxlength="2" value="" />
<label for="element_34_2">MM</label>
</span>
</fieldset>
<input id="element_509" value="" name="Subtotal"/>
</li> <li id="li_29" class="column_4">
<label class="description" for="element_29">Hours Billed <span id="required_29" class="required">*</span></label>
<div>
<input id="element_29" name="element_29" class="element text medium" type="text" data-quantity_link="element_44" value="" />
</div>
You definitely want to convert to a common unit (minutes) first.
It looks like you're attempting that with:
mins = mins / 60
but that's not correct.
{correction: it is technically correct, but you could potentially lose/gain time when converting back to your billing units. See the additional info below.}
You want something like:
var totalMinutes = mins + (hours * 60);
Also, fix the typo on line 7:
time2_1 = $("#element_33_2").val();
Should be:
time2_1 = $("#element_34_2").val();
Added:
To hide the NaNs and negative values, you could test the vars before assigning to val and also clear previous results if there are errors:
var val3 = (val1 - val2).toFixed(2);
if (isNaN(val3) || val3 < 0)
{
$("#element_29").val("");
}
else
{
$("#element_29").val(val3);
}
I would still recommend working with minutes-as-integers rather than hours-as-floats. The comments on this question have some good info on time reporting.

Doing math with Time using js

I have the following code:
HTML:
<form onsubmit="return false;">
<div class="col-5">
<label>
Page Time
<input id="pageTime" name="pageTime" type="time" step="1" tabindex="9">
</label>
</div>
<div class="col-5">
<label>
Ack Time
<input id="ackTime" name="ackTime" type="time" step="1" tabindex="10">
</label>
</div>
<div class="col-5">
<label>
Arrival Time
<input id="arrivalTime" name="arrivalTime" type="time" step="1" tabindex="11">
</label>
</div>
<div class="col-5">
<label>
Start Replace / Root Cause Found
<input id="startReplace" name="startReplace" type="time" step="1" tabindex="12">
</label>
</div>
<div class="col-5">
<label>
Replaced / Repair Completed
<input id="replaced" name="replaced" type="time" step="1" tabindex="13">
</label>
</div>
<div class="col-4">
<label>
Engagement
<input type="text" id="engagement" name="engagement" value="" readonly="readonly" />
</label>
</div>
<div class="col-4">
<label>
Arrival
<input type="text" id="arrival" name="arrival" value="" readonly="readonly" />
</label>
</div>
<div class="col-4">
<label>
Investigation
<input type="text" id="investigation" name="investigation" value="" readonly="readonly" />
</label>
</div>
<div class="col-4">
<label>
Mitigate
<input type="text" id="mitigate" name="mitigate" value="" readonly="readonly" />
</label>
</div>
<div class="col-1" style="text-align: center">
<label>
Total Ops Phases
<input type="text" name="totalOpsPhases" id="totalOpsPhases" value="" readonly="readonly" />
</label>
</div>
<div class="col-submit">
<button class="submitbtn" tabindex="14" onclick="opsTime();">Do the Math</button>
</div>
</form>
JS:
function toSeconds(time_str) {
// Extract hours, minutes and seconds
var parts = time_str.split(':');
var sum = 0;
// compute and return total seconds
for (c = 0; c <= 2; c++) {
if (c === 0) {
sum += parts[0] * 3600;
} else if (c === 1) {
sum += parts[1] * 60;
} else if (c === 2) {
if (parts[2] !== 'undefined') {
sum += parts[2];
}
}
}
return sum;
}
function opsTime() {
var time = [document.getElementById('pageTime').value, document.getElementById('ackTime').value, document.getElementById('arrivalTime').value, document.getElementById('startReplace').value, document.getElementById('replaced').value];
// Created an array to easily do the math :)
// Array mapping:
// 0 = pageTime
// 1 = ackTime
// 2 = arrivalTime
// 3 = startReplaceTime
// 4 = replacedTime
for (i = 0; i <= 4; i++) {
if (i === 4) {
var start = time[0];
var end = time[4];
} else {
start = time[i];
end = time[i + 1];
}
var startSec = toSeconds(start);
var endSec = toSeconds(end);
var difference = Math.abs(endSec - startSec);
// format time differnece
var result = [
Math.floor(difference / 3600), // an hour has 3600 seconds
Math.floor((difference % 3600) / 60), // a minute has 60 seconds
difference % 60
];
// 0 padding and concatation
result = result.map(function (v) {
return v < 10 ? '0' + v : v;
}).join(':');
var res = [];
res[i] = result;
}
document.getElementById('engagement').value = res[0];
document.getElementById('arrival').value = res[1];
document.getElementById('investigation').value = res[2];
document.getElementById('mitigate').value = res[3];
document.getElementById('totalOpsPhase').value = res[4];
}
What I'm trying to do is to pick the times filled in the inputs and show the difference in the inputs boxes below.
Engagement should be the time difference between Page Time and Ack Time;
Arrival should be the time difference between Ack Time and Arrival Time;
Investigation should be the time difference between Arrival and Start Replace Time;
Mitigate should be the time difference between Start Replace and Replaced time;
Total Ops Phases should be the time difference between Replaced and Page time.
I'm stuck on the code above for almost 8 hours, changed a lot of things trying to do the math and put each time difference inside an array and then use it to fill the inputs, but it seems the array isn't get filled with data.
Unfortunately I have to use the seconds as well, and I couldn't find much material with different solutions to calculate the difference of times using it.
I will be glad if someone can see another way to solve this matter.
Thanks in advance!
PS: Tried to insert a print of the form but I don't have the reputation needed.
The type="time" attribute is only supported by chrome, not Firefox or Internet Explorer so you should be using a compatibility library like these or one of your own making. If you just want to use chrome you can use valueAsNumber:
v.valueAsNumber
56013000
v.valueAsDate
Thu Jan 01 1970 10:33:33 GMT-0500 (EST)
v.value
"15:33:33"
Note that the Chrome console will show you these options with auto suggest.
Also jsfiddle

Categories

Resources