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>
Related
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>
<script>
function calculateAmount(val) {
var quantity = val;
if (quantity <= 100 && quantity < 1000){
var divobj = document.getElementById('discount');
divobj.value = 4;
var divobj1 = document.getElementById('yousaved');
var yousaved = 0.4 * quantity;
divobj1.value = yousaved;
}
}
</script>
<form>
<div class="form-group">
<label for=“quantity”>:</label>
<input type="quantity" class="form-control" id="quantity" aria-describedby="quantityHelp" placeholder="100 to 1000000" onchange="calculateAmount(this.value)" required>
<small id="quantityHelp" class="form-text text-muted">Any amount between 100 to 1000000.</small>
</div>
<div class="form-group">
<label for=“discount”>discount in %:</label>
<input type="discount" readonly class="form-control" id="discount" placeholder="Interest">
</div>
<div class="form-group">
<label for=“yousaved”>Total saving:</label>
<input type="yousaved" readonly class="form-control" id="yousaved" placeholder="Your Savings">
</div>
</form>
</div>
if (quantity <= 100 && quantity < 1000) condition not working, the only value accepted and get calculated is 100, and even var addition and multiplication is not working eg: quantity - quantity * 4/100
Based on text from your HTML (Number between 100 and 1000), the script should be:
<script>
function calculateAmount(val) {
var quantity = val;
if (quantity >= 100 && quantity <= 1000){
var divobj = document.getElementById('discount');
divobj.value = 4;
var divobj1 = document.getElementById('yousaved');
var yousaved = 0.4 * quantity;
divobj1.value = yousaved;
}
}
</script>
Yup, just a typo.
Probably better to just delete this question Arunkumar.
function calculateAmount(val) {
var quantity = val;
if (quantity >= 100 && quantity < 1000) {
var divobj = document.getElementById('discount');
divobj.value = 4;
var divobj1 = document.getElementById('yousaved');
var yousaved = 0.4 * quantity;
divobj1.value = yousaved;
}
}
<form>
<div class="form-group">
<label for=“quantity”>:</label>
<input type="quantity" class="form-control" id="quantity" aria-describedby="quantityHelp" placeholder="100 to 1000000" onchange="calculateAmount(this.value)" required>
<small id="quantityHelp" class="form-text text-muted">Any amount between 100 to 1000000.</small>
</div>
<div class="form-group">
<label for=“discount”>discount in %:</label>
<input type="discount" readonly class="form-control" id="discount" placeholder="Interest">
</div>
<div class="form-group">
<label for=“yousaved”>Total saving:</label>
<input type="yousaved" readonly class="form-control" id="yousaved" placeholder="Your Savings">
</div>
</form>
This question already has answers here:
How to calculate number of days between two dates?
(42 answers)
Closed 4 years ago.
I am facing one problem. I am unable to differentiate the date difference using the javascript. I am explaining my code below.
var startdate_val = document.getElementById("stdate").value;
var enddate_val = document.getElementById("enddate").value;
var one_day=1000*60*60*24;
var x=startdate_val.split("-");
var y=enddate_val.split("-");
var date1=new Date(x[2],(x[1]-1),x[0]);
var date2=new Date(y[2],(y[1]-1),y[0])
var month1=x[1]-1;
var month2=y[1]-1;
var date_diff = Math.ceil((date2.getTime()-date1.getTime())/(one_day));
console.log('date',date_diff <= 0);
Here I need enddate always should be greater than the start date. Here I am attaching my datetime code.
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="pad-bot-10">
<label for="raised">Start Date</label>
<input id="stdate" type="text" class="form-control datetime" value="" placeholder="17-06-2017"/>
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="pad-bot-10">
<label for="raised">End Date</label>
<input id="enddate" type="text" class="form-control datetime" value="" placeholder="17-06-2017"/>
</div>
</div>
</div>
Here I am getting the date field value like this i.e-03-01-2018 02:46. I need always the end date time should be greater than the start date time but in my case in console message always I am getting the result false.
Try this:
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="pad-bot-10">
<label for="raised">Start Date</label>
<input id="stdate" type="text" class="form-control datetime" value="17-06-2017" placeholder="17-06-2017"/>
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="pad-bot-10">
<label for="raised">End Date</label>
<input id="enddate" type="text" class="form-control datetime" value="17-07-2017" placeholder="17-06-2017"/>
</div>
</div>
</div>
var startdate_val = document.getElementById("stdate").value;
var enddate_val = document.getElementById("enddate").value;
var one_day=1000*60*60*24;
var x=startdate_val.split("-");
var y=enddate_val.split("-");
var date1=new Date(x[2],(x[1]-1),x[0]);
var date2=new Date(y[2],(y[1]-1),y[0])
var month1=x[1]-1;
var month2=y[1]-1;
var date_diff = Math.ceil((date2.getTime()-date1.getTime())/(one_day));
console.log(date_diff >= 0);
You just need to change the line: console.log('date',date_diff <= 0);
Simply do like this :
var startdate_val = document.getElementById("stdate").value;
var enddate_val = document.getElementById("enddate").value;
var stdate = new Date(startdate_val).toISOString();
var enddate = new Date(enddate_val).toISOString();
//Then
Console.log(enddate >= stdate);
Sample Code that I've tried:
var startdate_val = '01-03-2018 02:45';
var enddate_val = '01-03-2018 02:45';
var stdate = new Date(startdate_val);
var enddate = new Date(enddate_val);
//Then
alert(enddate >= stdate);
Returns True
Fiddle
Converting the string to Date Object will be better than the manual labor.
in your HTML code, there is no value so you can't compare it to page load time, because it is blank.
somehow if you are using any click functionality then
please update your code below.
var startdate_val = document.getElementById("stdate").value;
var enddate_val = document.getElementById("enddate").value;
var one_day = 1000 * 60 * 60 * 24;
var x = startdate_val.split("-");
var y = enddate_val.split("-");
var date1 = new Date(x[2], (x[1] - 1), x[0]);
var date2 = new Date(y[2], (y[1] - 1), y[0])
var month1 = x[1] - 1;
var month2 = y[1] - 1;
var date_diff = Math.ceil((date2.getTime() - date1.getTime()) / (one_day));
if (date_diff <= 0)
console.log(false);
else
console.log(true);
AND HTML FOR PAGE LOAD
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="pad-bot-10">
<label for="raised">Start Date</label>
<input id="stdate" type="text" class="form-control datetime" value="17-06-2017" placeholder="17-06-2017" />
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="pad-bot-10">
<label for="raised">End Date</label>
<input id="enddate" type="text" class="form-control datetime" value="18-06-2017" placeholder="17-06-2017" />
</div>
</div>
</div>
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.
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