I have an HTML Table used to generate a Calendar which shows TimeClock entries for each day a user has worked and clocked in and out of the system. Each day also shows the total time duration for each clock in/out entry. (multiple "timecard punches" can be within the same day)
Simply put I have DateTime style strings which hold a Duration value and I need to add them all together to get a combined duration value.
In a loop this JavaScript variable totalTimeValue will be assigned a duration value as a text string like this 03:31:23
Add these duration strings together using JavaScript...
03:31:23
04:21:56
04:08:42
03:31:17
04:10:59
02:48:21
04:26:11
00:00:39
03:41:37
Using JavaScript and jQuery I have this code below which gets the DateTime Duration value as a string in the format 04:21:19 for each timeclock entry.
My JavaScript/jQuery so far...
Demo of it working here: http://codepen.io/jasondavis/pen/GpPPPR?editors=101
var totalTimeValue = 0;
var totalWeekTimeValue = 0;
// itterate each week which is table row <tr>
$('#timeclock-cal > tbody > tr').each(function() {
console.log('=== New Week ===');
totalWeekTimeValue = 0;
// get each day which is a table cell <td>
$(this).find('td').each(function() {
console.log('== New Day ==');
// get total time val for each clock in/out on each day which is inside
// button with CSS class .cal-punch-total-time
$(this).find('.cal-punch-total-time').each(function() {
totalTimeValue = $(this).text();
console.log(totalTimeValue);
// THIS PART NEEDS YOUR HELP!
// NEED TO ADD EACH DATETIME STRING TOGETHER FOR TOTAL DURATION VALUES
totalWeekTimeValue = totalTimeValue+totalWeekTimeValue;
});
});
console.log('= total week time === '+totalWeekTimeValue);
});
full size image
I have no objection to using the MomentJS library http://momentjs.com/ if it can help in this situation however my research so far did not really show any examples doing what I need to do in this question.
In fact all my StackOverflow and Google searches resulted in no examples of adding durations like this in JavaScript!
I did find this MomentJS plugin MomentJS Durations - https://github.com/jsmreese/moment-duration-format
With JQuery and Javascript its easily possible. Please have a look at below code.
$(document).ready(function(){
var pad = function(num) { return ("0"+num).slice(-2); }
var totalSeconds = 0;
$("li").each(function(){
var currentDuration = $(this).text();
currentDuration = currentDuration.split(":");
var hrs = parseInt(currentDuration[0],10);
var min = parseInt(currentDuration[1],10);
var sec = parseInt(currentDuration[2],10);
var currDurationSec = sec + (60*min) + (60*60*hrs);
totalSeconds +=currDurationSec;
});
var hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
var minutes = Math.floor(totalSeconds / 60);
var seconds = totalSeconds % 60;
$(".totalVal").text(pad(hours)+":"+pad(minutes)+":"+pad(seconds));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
<li>03:31:23</li>
<li>04:21:56</li>
<li>04:08:42</li>
<li>03:31:17</li>
<li>04:10:59</li>
<li>02:48:21</li>
<li>04:26:11</li>
<li>00:00:39</li>
<li>03:41:37</li>
</ul>
<div id="totalTime">Total Time:<span class="totalVal"></span></div>
This is a little overkill, but shows how to use map and reduce.
/** Calculate the number of seconds from HH:MM:SS **/
function getSeconds(time) {
var parts = time.split(":");
return parseInt(parts[0], 10) * 3600 + parseInt(parts[1], 10) * 60 + parseInt(parts[2], 10);
}
//select all the elements
var totalSeconds = $("a.cal-punch-total-time")
.map( function(ind, elem) { //convert the jQuery object into the array
var text = $(elem).text(); //get the text from the anchor
return getSeconds(text); //set the index to the total seconds
})
.get() //gets the array out of the jQuery object
.reduce( function(runningTotal, currentValue){ //Now to combine all the values into one
return runningTotal + currentValue; //sum up the values
},0); //The initial starting vaule
//Now get the hour, minutes, and seconds from the total seconds
var hours = parseInt( totalSeconds / 3600 );
var minutes = parseInt( totalSeconds / 60 ) % 60;
var seconds = totalSeconds % 60;
//left pad numbers less than ten
if(hours<10) hours = "0" + hours;
if(minutes<10) minutes = "0" + minutes;
if(seconds<10) seconds = "0" + seconds;
$("#out").html("Total Time: " + (hours + ":" + minutes + ":" + seconds));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="cal-punch-total-time">03:31:23</a>
<a class="cal-punch-total-time">04:21:56</a>
<a class="cal-punch-total-time">04:08:42</a>
<a class="cal-punch-total-time">03:31:17</a>
<a class="cal-punch-total-time">04:10:59</a>
<a class="cal-punch-total-time">02:48:21</a>
<a class="cal-punch-total-time">04:26:11</a>
<a class="cal-punch-total-time">00:00:39</a>
<a class="cal-punch-total-time">03:41:37</a>
<div id="out"></div>
Try this:
function hhmmssToSeconds(str) {
var arr = str.split(':').map(Number);
return (arr[0] * 3600) + (arr[1] * 60) + arr[2];
};
function secondsToHHMMSS(seconds) {
var hours = parseInt(seconds / 3600, 10),
minutes = parseInt((seconds / 60) % 60, 10),
seconds = parseInt(seconds % 3600 % 60, 10);
return [hours, minutes, seconds].map(function (i) { return i.toString().length === 2 ? i : '0' + i; }).join(':');
}
Then:
var t1 = hhmmssToSeconds('40:50:40'),
t2 = hhmmssToSeconds('04:12:30');
var result = secondsToHHMMSS(t1 + t2); // '45:03:10'
You can split your DateTime strings into arrays.
totalTimeValue = $(this).text().split(':'); //from '03:10:30' to ['03','10','30']
Then loop through your array and coerce each string to a number.
totalTimeValue.forEach(function(val,idx){
totalWeekTimeValue[idx] += Number(val);
});
This will leave you with an array of values for totalWeekTime that you can format/recalculate and rejoin if needed.
totalWeekTimeValue.join(':'); //[3:10:30]
http://codepen.io/hirechrismeyers/pen/ZbVVgr
Related
I'm a bit stuck with a javascript countdown script. It is designed to grab the amount of time from a div and then count this down and submit a form.
Here is the code:
function secondPassed() {
var str=$("#countdown").text();
var pieces = str.split(":");
var seconds = (Number(pieces[0]) * 60) + Number(pieces[1]);
var minutes = Math.round((seconds - 30) / 60);
remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.qForm.submit();
} else {
seconds--;
}
}
var countdownTimer = setInterval(secondPassed, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Question 1 of 20<time id="countdown">5:00</time></h3>
<form name="qForm">
<input type="radio"> 219
<input type="submit" value="Submit">
</form>
The issue is found in the first few lines which I have had to modify. How do I get it to grab the text from my time tag, but instead I'm stuck with it being like this:
var pieces = str.split(":");
How do I get it to pull in the time value from my time tag instead?
Actually, your logic can be greatly simplified. What you need to realize is that since you are reading from the .innerHTML of the element, you will have to update it so that you actually successfully decrement the time: otherwise you are perpetually stuck at the starting time, since you are reading from the text node and yet it is never updated.
Step 1: Reading the .innerHTML of your element
In order to get the innerHTML of the <time> element, you can do it as simple as:
var pieces = document.getElementById('countdown').innerHTML.split(":");
However, we can always cache this DOM node, since we need to update its innerHTML later anyway:
var countdown = document.getElementById('countdown');
var pieces = countdown.innerHTML.split(":");
Step 2: Counting down
You've got the time parsing logic correct, so all you need is to keep track of the total seconds left on your clock, and remember to decrement it by 1 second:
var totalSeconds = (Number(pieces[0]) * 60) + Number(pieces[1]);
// Countdown
totalSeconds--;
Step 3. Update your <time> element so that countdown time is updated
Here we simply get decremented totalSeconds, and calculate the remaining minutes and seconds left. Minutes left is simply the total seconds divided by 60 and floored, while seconds left is simply the modulus of total seconds. You've got the calculations right to begin with, I simply made it easier to read.
Then, you want to update your countdown element's innerHTML (remember that we cahced that DOM node in step 1?). We use tenary operators to simplify the logic of adding 0 to the front of single-digit seconds:
// Update <time>
var currentMinutes = Math.floor(totalSeconds / 60);
var currentSeconds = totalSeconds % 60;
countdown.innerHTML = currentMinutes + ':' + (currentSeconds < 10 ? '0' + currentSeconds : currentSeconds);
Step 4: Check if timer has run out
This is the simple part: at the end of everything, just check if totalSeconds is now 0. If it is, clear the interval and submit the form:
// Submit form when we hit 0
if (totalSeconds === 0) {
window.clearInterval(countdownTimer);
document.getElementById('qForm').submit();
}
Here is a proof-of-concept example, but I have substituted the time so that we have 5 seconds to countdown (to simplyify testing) and that the form submission is commented out and replaced by an alert():
function secondPassed() {
var countdown = document.getElementById('countdown');
var pieces = countdown.innerHTML.split(":");
var totalSeconds = (Number(pieces[0]) * 60) + Number(pieces[1]);
// Countdown
totalSeconds--;
// Update <time>
var currentMinutes = Math.floor(totalSeconds / 60);
var currentSeconds = totalSeconds % 60;
countdown.innerHTML = currentMinutes + ':' + (currentSeconds < 10 ? '0' + currentSeconds : currentSeconds);
// Submit form when we hit 0
if (totalSeconds === 0) {
window.clearInterval(countdownTimer);
alert('Will submit form!');
// document.getElementById('qForm').submit();
}
}
var countdownTimer = setInterval(secondPassed, 1000);
<h3>Question 1 of 20<br /><time id="countdown">0:05</time></h3>
<form name="qForm">
<input type="radio"> 219
<input type="submit" value="Submit">
</form>
Alternative recommendation: store data in HTML5 data- attribute
It's often not ideal to read data directly from innerHTML of a DOM node, because sometimes you might want to update the HTML without affected the stored data. In that case, you can always use the HTML5 dataset API, where arbitrary data is stored in data- attributes.
In the code snippet below, we can store the countdown in the date-countdown attribute:
<time id="countdown" data-countdown="0:05"></time>
And we can simply create a helper function to synchronize the data-countdown value and write it to the innerHTML:
function updateTimer() {
var countdown = document.getElementById('countdown');
countdown.innerHTML = countdown.dataset.countdown;
}
You can call this function:
On pageload, and
Every time the countdown is updated
See the updated proof-of-concept below:
function secondPassed() {
var countdown = document.getElementById('countdown');
var pieces = countdown.dataset.countdown.split(":");
var totalSeconds = (Number(pieces[0]) * 60) + Number(pieces[1]);
// Countdown
totalSeconds--;
// Update <time>
var currentMinutes = Math.floor(totalSeconds / 60);
var currentSeconds = totalSeconds % 60;
countdown.dataset.countdown = currentMinutes + ':' + (currentSeconds < 10 ? '0' + currentSeconds : currentSeconds);
// Update innerHTML
updateTimer();
// Submit form when we hit 0
if (totalSeconds === 0) {
window.clearInterval(countdownTimer);
alert('Will submit form!');
// document.getElementById('qForm').submit();
}
}
function updateTimer() {
var countdown = document.getElementById('countdown');
countdown.innerHTML = countdown.dataset.countdown;
}
var countdownTimer = setInterval(secondPassed, 1000);
updateTimer();
<h3>Question 1 of 20<br /><time id="countdown" data-countdown="0:05"></time></h3>
<form name="qForm">
<input type="radio"> 219
<input type="submit" value="Submit">
</form>
Not entirely sure why you would want to be select this from the DOM, would it not just be better to know you are calculating 5 minutes and save yourself the hassle of parsing the value from the DOM.
Alternatively, set the 'datetime' property of the tag.
https://www.w3schools.com/tags/tag_time.asp
See below for an example of reading this:
https://www.w3schools.com/jsref/prop_time_datetime.asp
You can use below code
var countdownTimer;
function secondPassed() {
var str = document.getElementById('countdown').innerHTML;
var pieces = str.split(":");
var seconds = (Number(pieces[0]) * 60) + Number(pieces[1]);
console.log(seconds);
var minutes = 0;
if (seconds == 0) {
clearInterval(countdownTimer);
// document.qForm.submit();
} else {
seconds--;
}
minutes = Math.floor(seconds / 60);
document.getElementById('countdown').innerHTML = minutes+':'+ (seconds%60);
}
countdownTimer = setInterval(secondPassed, 1000);
You could use momentJS to convert the time into a duration (a little overkill though) and setting an end date with it, like so:
function convertStringToDuration( s ) {
// Just in case, if you plan to use hours as well in the future :)
const parameterNames = [ 'hours', 'minutes', 'seconds' ];
const parts = s.split( ':' );
// Generate moment.duration parameters
const parameters = parameterNames.slice( -parts.length ).reduce( ( result, param, index ) => {
result[ param ] = parseInt( parts[ index ], 10 );
return result;
}, {} );
return moment.duration( parameters );
}
function pass( timer, element, end, callback ) {
// get the current time
const now = moment();
// calculate duration
let duration = end - now;
if ( duration <= 0 ) {
duration = 0;
clearInterval( timer );
if ( typeof callback === 'function' ) {
callback();
}
}
// and format time
const formatted = moment.utc( duration ).format( 'm:ss' );
element.innerText = formatted;
}
function action() {
console.log( 'Done' );
}
const countdown = document.querySelector( '#countdown' );
const duration = convertStringToDuration( countdown.innerText );
// set end time
const end = moment().add( duration );
let countdownTimer = setInterval( () => pass( countdownTimer, countdown, end, action ), 250 );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.0/moment.min.js"></script>
<h3>Question 1 of 20<br><time id="countdown">5:00</time></h3>
<form name="qForm">
<input type="radio"> 219
<input type="submit" value="Submit">
</form>
I have start date time and end time,i need to split how many days , hours ,minutes in the two dates
for example ,
startdatetime = "09-06-2017 10:30"
enddatetime = "10-06-2017 11:45"
i need this result : 1 day 1 hour and 15 minutes
I try this one
var t = end - start;
var z = parseInt(t / 1000 / 60);
var time = display(z);
function display(a)
{
console.log(a);
var hours = Math.trunc(a/60);
var minutes = a % 60;
var one_day=1000*60*60*24
var days = Math.ceil(a/one_day)
var time = [hours,minutes,days];
return time;
}
i get the following 1day 24 hours and 15 minutes , can anyone help me , if its new logic means i will change into it,thanks in advance
Using momentjs, you can :
Parse your input string using moment(String, String)
Parse your input string using moment.utc
Get difference using diff() function
Create a duration from the difference value
Use duration days(), hours(), minutes() to get your result
Here a live sample:
var startdatetime = "2017-06-09T07:00:01.000Z";
var enddatetime = "2017-06-10T09:00:00.000Z";
// Parse input
var mStart = moment.utc(startdatetime);
var mEnd = moment.utc(enddatetime);
// Calculate difference and create duration
var dur = moment.duration( mEnd.diff(mStart) );
// Show the result
console.log(dur.days() + ' days ' + dur.hours() + ' hour ' + dur.minutes() + ' minutes');
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
If you want you can use moment-duration-format plug-in to get the same result using format() method on duration. Here a working sample:
var startdatetime = "2017-06-09T07:00:01.000Z";
var enddatetime = "2017-06-10T09:00:00.000Z";
// Parse input
var mStart = moment.utc(startdatetime);
var mEnd = moment.utc(enddatetime);
// Calculate difference and create duration
var dur = moment.duration( mEnd.diff(mStart) );
// Show the result
console.log(dur.format('d [day] h [hour] m [minutes]'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
Well, if you look at documentation for javascript Date objects, there is a getTime() method . You can also use the valueOf() method. They both return the number of milliseconds representing your Date object.
You can simply call that on both Date objects and then find the difference. Once you have the difference you can find the amount of secs, mins , hrs, days, etc. Here is an example:
var start = new Date(*some date*);
var end = new Date(*some date*);
var dif = end.valueOf() - start.valueOf();
if (dif >= 0) {
var secs = Math.floor(dif / 1000 % 60);
var mins = Math.floor(dif / 1000 / 60 % 60);
var hrs = Math.floor(dif / 1000 / 60 / 60 % 24);
var days =
Math.floor(dif / 1000 / 60 / 60 / 24 % 365);
var yrs =
Math.floor(dif / 1000 / 60 / 60 / 24 / 365);
Try the following:
var t = end - start;
var z = parseInt(t / 1000 / 60);
var time = display(z);
function display(minutes)
{
var hours = (minutes / 60 | 0) % 24;
var minutes = (minutes | 0) % 60;
var days = minutes / 60 / 24 | 0;
return [hours, minutes, days];
}
Note that in javascript, doing x | 0 is the same as Math.floor(x).
It looks to me like your calculation for hours still has the days in it. Once you have established the days, just subtract those out when you calculate the hours.
var start = new Date("June 09, 2017 10:30:00");
var end = new Date("June 10, 2017 11:45:00");
var t = end - start;
var z = parseInt(t / 1000 / 60);
var time = display(z);
console.log(time);
function display(a)
{
var minutes = a % 60;
var one_day=1000*60*60*24
var days = Math.ceil(a/one_day)
var hours = Math.trunc((a-(days*1440))/60);
var time = [hours,minutes,days];
return time;
}
Having said that, I highly recommend moment.js to handle this type of thing, if you can.
var startDateTime = 1497029400000;
var endDateTime = 1497120300000;
var timeDifference = endDateTime - startDateTime
// with the given dates, days equals 1.0520833333333333
// we want to extract the trailing decimal values using modulus to get the other times
function getTimeDifference(timeDifference) {
var days = timeDifference/1000/60/60/24
days >= 1
? var dayCount = Math.trunc(days); // store the day count
: var dayCount = 0; // it is less than one day
// get the remaining hours
var hours = (days % 1) * 24;
var hoursCount = Math.trunc((days % 1) * 24);
// get the remaining minutes
var minutesCount = Math.ceil((hours % 1) * 60);
}
I need for a clock to count from a specific time. e.g. Time is 20:08:00 and then to count from there. I have searched high and low for an answer and no one has specifically come up with an answer(that Ive seen). So my normal clock is like this.
<script type="text/javascript">
function clock()
{
var digital = new Date();
var hours = digital.getHours();
var minutes = digital.getMinutes();
var seconds = digital.getSeconds();
if (minutes <= 9) minutes = "0" + minutes;
if (seconds <= 9) seconds = "0" + seconds;
dispTime = hours + ":" + minutes + ":" + seconds;
var basicclock = document.getElementById('basicclock');
basicclock.innerHTML = dispTime;
setTimeout("clock()", 1000);
}
clock();
</script>
So all I need is the time to start at say 20:08:00 (or a variable of time). I am wondering if it better to use a timer to achieve a set time and to count from that???
Any help would be appreciated.
First: Please try to extensively search SO for answers before asking questions, many helpful responses can be found if you look. ;)
If you are trying to countdown to a certain time/date I would recommend the answer found HERE
All code credit goes to author's answer above.
HTML - for display
<span id="days"></span>
<span id="hours"></span>
<span id="minutes"></span>
<span id="seconds"></span>
Script (keep formatting and just modify the 4th line down for your target date)
setInterval(function(){
// set whatever future date / time you want here, together with
// your timezone setting...
var future = new Date("Sep 20 2014 21:15:00 GMT+0200");
var now = new Date();
var difference = Math.floor((future - now) / 1000);
var seconds = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);
var minutes = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);
var hours = fixIntegers(difference % 24);
difference = Math.floor(difference / 24);
var days = difference;
$("#seconds").text(seconds + "s");
$("#minutes").text(minutes + "m");
$("#hours").text(hours + "h");
$("#days").text(days + "d");
}, 1000);
function fixIntegers(integer)
{
if (integer < 0)
integer = 0;
if (integer < 10)
return "0" + integer;
return "" + integer;
}
DEMO OF THE ABOVE CODE
I would also look at these are other interesting solutions found on this post here HERE
I am trying to compare two dates in javascript, which are in two input type="text", and that have the format "06/11/2013 13:24".
Any idea of how to compare them?
Thanks!
You need to parse string to Date - object:
var firstDate = new Date("06/11/2013 13:24");
var secondDate = new Date(youSecondDateString);
Age from Date of Birth using JQuery
Possibly a duplicate question to above but the answers is
var startDt=document.getElementById("startDateId").value;
var endDt=document.getElementById("endDateId").value;
if( (new Date(startDt).getTime() > new Date(endDt).getTime()))
{
//perform desired operation here
}
The Date object will do what you want - construct one for each date, then just compare them using the usual operators.
For example, subtracting date1 from date2 will give you the number of milliseconds between two dates.
You can get the number of seconds by dividing the milliseconds by 1000, and rounding the number:
var seconds = Math.round((date2-date1)/1000);
You could then divide by 60 to get the minutes, again by 60 to get the hours, then by 24 to get the days (and so on).
Here's how you might get a figure in the format dd:hh:mm
window.minutesPerDay = 60 * 24;
function pad(number) {
var result = "" + number;
if (result.length < 2) {
result = "0" + result;
}
return result;
}
function millisToDaysHoursMinutes(millis) {
var seconds = millis / 1000;
var totalMinutes = seconds / 60;
var days = totalMinutes / minutesPerDay;
totalMinutes -= minutesPerDay * days;
var hours = totalMinutes / 60;
totalMinutes -= hours * 60;
return days + ":" + pad(hours) + ":" + pad(totalMinutes);
}
var date1 = new Date("06/11/2013 13:24"),
date2 = new Date("07/11/2013 13:24"),
milliseconds = date2 - date1;
alert(millisToDaysHoursMinutes(milliseconds));
Fiddle
I took the millisToDaysHoursMinutes function from here.
I'm looking for js that does something similar to this: http://www.unitarium.com/time-calculator.
My song-lengths are in an array, not in form fields. And the result have to display hh:mm:ss when needed (or always).
This is the page I want to use this on: http://flamencopeko.net/songs.php.
Make a function to convert the format mm:ss to seconds, and one to convert seconds to the format hh:mm:ss, convert all values to seconds, add them together, and format the result:
function parseMS(s) {
var parts = s.split(':');
return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
}
function formatTwo(n) {
return (n < 10 ? '0' : '') + n.toString();
}
function formatHMS(s) {
var m = Math.floor(s / 60);
s %= 60;
var h = Math.floor(m / 60);
m %= 60;
return formatTwo(h) + ':' + formatTwo(m) + ':' + formatTwo(s);
}
var times = ['14:23', '11:08', '18:59'];
var sum = 0;
for (var i = 0; i < times.length; i++) sum += parseMS(times[i]);
var result = formatHMS(sum);
alert(result);
Demo: http://jsfiddle.net/u6B4g/
I was able to use this PHP:
$str_time = "2:50";
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$time_seconds = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes;
from Convert time in HH:MM:SS format to seconds only? to make bars for my song-lengths here: http://flamencopeko.net/songs.php.
I'll try to use that to get total playing time now.
I think array_sum() is the way to go, but I don't know how.
Up to date source: http://flamencopeko.net/covers.txt.