How can I sum time in javascript?
01:00:00
00:30:00
00:30:00
I have times like above I want the sum of the given time, like
sum of above time = 02:00:00
If I use the JavaScript methods setHours() and setMinutes() these function replace old time and show newly added time like:
new Date(new Date(0, 0, 0, 00, 00, 00, 0)).setMinutes(30)
new Date(new Date(new Date(0, 0, 0, 00, 00, 00, 0)).setMinutes(30)).setMinutes(30);
The result of both conditions the same but I want here 00:30 + 00:30 = 01:00.
Some functions to help you go back and forth between the formatted length of time and seconds as an integer:
function timestrToSec(timestr) {
var parts = timestr.split(":");
return (parts[0] * 3600) +
(parts[1] * 60) +
(+parts[2]);
}
function pad(num) {
if(num < 10) {
return "0" + num;
} else {
return "" + num;
}
}
function formatTime(seconds) {
return [pad(Math.floor(seconds/3600)),
pad(Math.floor(seconds/60)%60),
pad(seconds%60),
].join(":");
}
You can use them to achieve what you want:
time1 = "02:32:12";
time2 = "12:42:12";
formatTime(timestrToSec(time1) + timestrToSec(time2));
// => "15:14:24"
Try this :
var time1 = "01:00:00";
var time2 = "00:30:00";
var time3 = "00:30:00";
var hour=0;
var minute=0;
var second=0;
var splitTime1= time1.split(':');
var splitTime2= time2.split(':');
var splitTime3= time3.split(':');
hour = parseInt(splitTime1[0])+parseInt(splitTime2[0])+parseInt(splitTime3[0]);
minute = parseInt(splitTime1[1])+parseInt(splitTime2[1])+parseInt(splitTime3[1]);
hour = hour + minute/60;
minute = minute%60;
second = parseInt(splitTime1[2])+parseInt(splitTime2[2])+parseInt(splitTime3[2]);
minute = minute + second/60;
second = second%60;
alert('sum of above time= '+hour+':'+minute+':'+second);
If you want to use a Date object for this, you can, you just have to be sure to include the current value for the unit you're changing when adding to it, like so:
var dt = new Date(0, 0, 0, 0, 0, 0, 0);
dt.setHours(dt.getHours() + 1); // For the 01:00
dt.setMinutes(dt.getMinutes() + 30); // For the first 00:30
dt.setMinutes(dt.getMinutes() + 30); // For the second 00:30
display("Hours: " + dt.getHours());
display("Minutes: " + dt.getMinutes());
function display(msg) {
var p = document.createElement("p");
p.innerHTML = String(msg);
document.body.appendChild(p);
}
Technically, of course, the first time you know getHours and getMinutes will return 0, but for consistency, best to just always include them.
This solution is perfect:
function timestrToSec(timestr) {
var parts = timestr.split(":");
return (parts[0] * 3600) +
(parts[1] * 60) +
(+parts[2]);
}
function pad(num) {
if(num < 10) {
return "0" + num;
} else {
return "" + num;
}
}
function formatTime(seconds) {
return [pad(Math.floor(seconds/3600)%60),
pad(Math.floor(seconds/60)%60),
pad(seconds%60),
].join(":");
}
but there is a little bug in the last function "formatTime" !
return [pad(Math.floor(seconds/3600)%60), => return [pad(Math.floor(seconds/3600)),
so without %60!!
Becouse if i have to sum hour, it can be greater than 60 (H)
This work for me:
function padnum(n){return n<10 ? '0'+n : n}
var time1 = "00:30";
var time2 = "00:60";
var minute=0;
var second=0;
var splitTime1= time1.split(':');
var splitTime2= time2.split(':');
minute = parseInt(parseInt(splitTime1[0]))+parseInt(splitTime2[0]);
second = parseInt(parseInt(splitTime1[1]))+parseInt(splitTime2[1]);
minute = minute + second/60;
minute =parseInt(minute);
second = second%60;
minute = padnum(minute);
second = padnum(second);
alert('sum of above time= '+minute+':'+second);
Here is a function with error handling included.
Even though it's a big function it results in an useful one-liner. Just pass an array with values and you're good to go.
function sumMinutes(values) {
const validate = time => {
if (time > 59 || time < 0) {
throw new Error(
"Hours, minutes and seconds values have to be between 0 and 59."
);
}
return time;
};
const seconds = values
.map(e => validate(Number(e.split(":").reverse()[0])))
.reduce((a, b) => a + b);
let minutes = values
.map(e => Number(e.split(":").reverse()[1]))
.reduce((a, b) => a + b);
let hours = values
.map(e =>
e.split(":").reverse()[2] ? Number(e.split(":").reverse()[2]) : 0
)
.reduce((a, b) => a + b);
minutes *= 60;
hours *= 3600;
let result = new Date((hours + minutes + seconds) * 1000)
.toISOString()
.substr(11, 8);
return result.split(":").reverse()[2] === "00" ? result.slice(3) : result;
}
/* examples */
const seconds = ["00:03", "00:9"];
const mins = ["01:20", "1:23"];
const hours = ["00:03:59", "02:05:01"];
const mix = ["00:04:58", "10:00"];
console.log(sumMinutes(seconds)); //'00:12'
console.log(sumMinutes(mins)); //'02:43'
console.log(sumMinutes(hours)); //'02:09:00'
console.log(sumMinutes(mix)); //'14:58'
Here how I handled, If you sum only hours, the function returns total hours and minutes, not days.
function timeToMins(time) {
var b = time.split(':');
return b[0] * 60 + +b[1];
};
function timeFromMins(mins) {
function z(n) {
if (n < 0) return ('-0' + (n).toString().slice(1));
return (n < 10 ? '0' : '') + n;
};
var h = (mins / 60 | 0);
var m = mins % 60;
return z(h) + ':' + z(m);
};
function addTimes(time0, time1) {
return timeFromMins(timeToMins(time0) + timeToMins(time1));
};
addTimes('02:30', '-00:30');
The output will be: 02:00
// Array [0] 01:00:00
// Array [1] 00:30:00
// Array [2] 00:30:00
let time = '01:00:00';
time = addTimes(time, '00:30:00');
time = addTimes(time, '00:30:00');
The output will be: 02:00
I did it keeping things simple.
This is my approach:
function sumTime(time1, time2) {
const splitTime1= time1.split(':');
const splitTime2= time2.split(':');
let hour = parseInt(splitTime1[0])+parseInt(splitTime2[0]);
let minute = parseInt(splitTime1[1])+parseInt(splitTime2[1]);
let second = parseInt(splitTime1[2])+parseInt(splitTime2[2]);
// Fix seconds, example: 400:60:124 -> 400:62:04
minute = minute + (Math.floor(second/60)); // 124 / 60 = 2.07 -> +2 minutes
second = Math.floor(second%60) // 124 % 60 = 4 -> 4 seconds
// Fix minutes, example: 400:62:04 -> 401:02:04
hour = hour + (Math.floor(minute/60)) // 62 / 60 = 1.03 -> +1 hour
minute = Math.floor(minute%60) // 62 % 60 = 2 -> 2 minutes
// Formatting fields
hour = hour.toString().padStart(2,'0');
minute = minute.toString().padStart(2,'0');
second = second.toString().padStart(2,'0');
return `${hour}:${minute}:${second}`;
}
Existing answers hardcode the hours minutes and seconds, but a dynamic approach is to split on the : delimiter and accumulate, multiplying each chunk by 60 and adding it to the next chunk. After doing this, the last element contains the total seconds, which can be converted to h:m:s.
const sumToSeconds = times => {
return times.reduce((a, e) => {
const parts = e.trim().split(":").map(Number);
parts.forEach((e, i) => {
if (i < parts.length - 1) {
parts[i+1] += e * 60;
}
});
return parts.pop() + a;
}, 0);
};
const times = [
"4:50",
"2:02",
"1:38",
"2:49",
"2:49",
"2:13",
"2:20",
"2:12",
"2:44",
"4:23",
"55:23",
"1:01:02",
];
const totalSeconds = sumToSeconds(times);
console.log(
`${~~(totalSeconds / 60 / 60)} hours, ${
~~((totalSeconds / 60) % 60)} minutes, ${
~~(totalSeconds % 60)} seconds`
); // => 2 hours, 24 minutes, 25 seconds
The h:m:s part can be made dynamic too, if desired:
const sumToSeconds = times => {
return times.reduce((a, e) => {
const parts = e.trim().split(":").map(Number);
parts.forEach((e, i) => {
if (i < parts.length - 1) {
parts[i+1] += e * 60;
}
});
return parts.pop() + a;
}, 0);
};
const toHMS = time => {
const labels = ["hours", "minutes", "seconds"];
return Object.fromEntries(
labels.map((e, i) => [
e,
~~(time / 60 ** (labels.length - i - 1)) % 60,
])
);
};
const times = [
"4:50",
"2:02",
"1:38",
"2:49",
"2:49",
"2:13",
"2:20",
"2:12",
"2:44",
"4:23",
"55:23",
"1:01:02",
];
console.log(toHMS(sumToSeconds(times)));
// => { hours: 2, minutes: 24, seconds: 25 }
As an aside, if I may nitpick on your question a bit,
01:00:00
00:30:00
00:30:00
isn't a great test case to pick because it doesn't exercise the code thoroughly. A test with some hour and minute values would be better.
Related
I want to accurately display the difference between two times. The different should be displayed in a format such as mm:ss
methods: {
calcuateTimeDifference: function (startTime, endTime) {
let result = 0;
if (startTime && endTime) {
let start = startTime.split(":");
let end = endTime.split(':');
let startTimeInHrs = (parseFloat(start[0]/3600) + parseFloat(start[1]/60) + parseFloat(start[2]/3600));
let endTimeInHrs = (parseFloat(end[0]/3600) + parseFloat(end[1]/60) + parseFloat(end[2] /3600));
result = endTimeInHrs - startTimeInHrs;
}
return result.toFixed(2);
},
Using this function - the difference between the following times: 16:03:01 - 16:04:01 - I get the result as -32.00.
split the strings on : to get the hours, minutes, and seconds
convert all to seconds and add them to get the total seconds from each time
subtract the two to get the difference in seconds
convert the difference seconds to hours, minutes and seconds using the modules operator(%)
format the result for appropriate display
let start = "16:03:01";
let end = "16:04:05";
let time = calcuateTimeDifference(start, end);
console.log(time);
function calcuateTimeDifference(startTime, endTime) {
let result = 0;
if (startTime && endTime) {
const start = startTime.split(':').map(Number);
const end = endTime.split(':').map(Number);
const startSeconds = (60*60) * start[0] + 60*start[1] + start[2];
const endSeconds = (60*60) * end[0] + 60*end[1] + end[2];
const diffSeconds = endSeconds - startSeconds;
seconds = parseInt((diffSeconds) % 60);
minutes = parseInt((diffSeconds/60) % 60);
hours = parseInt((diffSeconds/(60*60)) % 24);
//append `0` infront if a single digit
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return `${hours}:${minutes}:${seconds}`;
}
console.log("Invalid Input");
}
function calcuateTimeDifference(startTime, endTime) {
let toSeconds = (time) => {
let [h, m, s] = time.split(':');
return h * 360 + m * 60 + +s;
};
let d = Math.abs(toSeconds(startTime) - toSeconds(endTime));
let mm = String(Math.floor(d / 60));
if (mm.length == 1) mm = '0' + mm;
let ss = String(d % 60);
if (ss.length == 1) ss = '0' + ss;
return `${mm}:${ss}`;
}
I have a start date, time and end date, time and also i am finding out the total duration of travel. The output is in millisecond and i need to convert this into hours format. By searching other answers here i tried the following but no result.
<md-cell *mdCellDef="let row"> {{row?.duration | formatDuration}} </md-cell>
And ts file:
export class StoppageComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
filter('formatDuration', function () {
return function (input) {
var totalHours, totalMinutes, totalSeconds, hours, minutes, seconds, result='';
totalSeconds = input / 1000;
totalMinutes = totalSeconds / 60;
totalHours = totalMinutes / 60;
seconds = Math.floor(totalSeconds) % 60;
minutes = Math.floor(totalMinutes) % 60;
hours = Math.floor(totalHours) % 60;
if (hours !== 0) {
result += hours+':';
if (minutes.toString().length == 1) {
minutes = '0'+minutes;
}
}
result += minutes+':';
if (seconds.toString().length == 1) {
seconds = '0'+seconds;
}
result += seconds;
return result;
};
});
}
I think the error is with ts file, as i am new in angular.
Is there is any direct conversion using pipe without using functions?
Other answers looks complicated, finally found out a solution myself..
Html as,
<md-cell *mdCellDef="let row"> {{getFormathours(row?.duration)}} </md-cell>
And ts,
getFormathours(input) {
var totalHours, totalMinutes, totalSeconds, hours, minutes, seconds, result='';
totalSeconds = input / 1000;
totalMinutes = totalSeconds / 60;
totalHours = totalMinutes / 60;
seconds = Math.floor(totalSeconds) % 60;
minutes = Math.floor(totalMinutes) % 60;
hours = Math.floor(totalHours) % 60;
console.log (hours + ' : ' + minutes + ' : ' + seconds);
if (hours !== 0) {
result += hours+' hr:';
if (minutes.toString().length == 1) {
minutes = '0'+minutes;
}
}
result += minutes+' min';
if (seconds.toString().length == 1) {
seconds = '0'+seconds;
}
result += seconds;
return result;
}
This gives the exact output that i needed and much more clear solution based on my question.. Anyhow i appreciate others answers too for your effort.
You do not need to reinvent the wheel. You can use Date objects to get duration.
Assuming you have 2 date objects,
Get the difference between them. Since you already have millseconds, you already have completed this step.
Now create a new date object and remove time value.
Now when you set new time value(difference) to it, you have all the values. Just use the function and get the values and display in your format.
function getTravelDuration(date1, date2) {
var diff = +date2 - +date1;
var today = new Date();
today.setHours(0,0,0,0);
var arrival = new Date(+today + diff);
var duration = ['getFullYear', 'getMonth', 'getDate', 'getHours', 'getMinutes', 'getSeconds'].reduce(function(p,c,i,a){
var value = arrival[c]() - today[c]();
if(value) {
p += value;
p += ((c === 'getFullYear') ? ' Year' : c.replace('get', ' ')) + ' '
}
return p;
}, '');
console.log(duration);
}
function doubleDigits(str){
return ('00' + str).slice(-2)
}
getTravelDuration(new Date(2017, 10, 5, 5), new Date(2017, 10, 5, 15, 23));
getTravelDuration(new Date(2017, 10, 5, 5), new Date(2017, 10, 6, 15, 23, 30));
For me, the best choice (without errors) is use the moment library, instead Date.
Please check https://momentjs.com/docs/
var t1 = moment('2017/10/5 15:23');
var t2 = moment('2017/10/5 15:23');
var differenceMinutes = t1.diff(t2, 'minutes');
var differenceMilliseconds = t1.diff(t2, 'minutes');
Using popular and tested libraries, could be better. You can use in angular templates:
https://github.com/urish/angular2-moment
Example:
{{startDate | amDifference: endDate :'' }}
you can use this code directly
export class StoppageComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
filter('formatDuration', function () {
return function (input) {
var result = new Date(input);
var n = (d.getDate().toString()) +'/'+ (d.getMonth().toString())+'/' +(d.getFullYear().toString()) + ' '+ (d.getHours().toString()) +':'+ (d.getHours().toString()) +':'+ (d.getSeconds().toString());
return result;
};
});
}
So let's say we have two times:
7:30 - 12:00
So my question is how can I generate an array with times like this:
7:30, 8:00, 8:30, 9:00, 9:30, 10:00, 10:30, 11:00, 11:30
I need this for a booking, so let's say the business will open at 7:30 and every booking that you can make will be 30 min(this time can change, could be one hour or more)
Whats the best way to generate something like this in JS?
Little verbose utility, you can use it..
var getTimeIntervals = function (time1, time2, slotInMinutes, workingHourStart, workingHourEnd) {
time1.setMinutes(0); time1.setSeconds(0);
var arr = [];
var workingHoursStart = workingHourStart;
var workingHourEnds = workingHourEnd;
var workingHourStartFloat = parseFloat("7:30");
var workingHourEndFloat = parseFloat("12:00");
while(time1 < time2){
var generatedSlot = time1.toTimeString().substring(0,5);
var generatedSlotFloat = parseFloat(generatedSlot);
time1.setMinutes(time1.getMinutes() + slotInMinutes);
if(generatedSlotFloat >= workingHourStartFloat && generatedSlotFloat < workingHourEndFloat){
var generatedObject = {
slot: time1.toTimeString().substring(0,5),
timeStamp: new Date(time1.getTime())
};
arr.push(generatedObject);
}
}
return arr;
}
var today = new Date();
var tomrorow = new Date().setDate(today.getDate()+1);
console.log(getTimeIntervals(today, tomorrow, 30, "7:30", "12:00"));
Function getTimeIntervals expects startDate, endDate, slotDurationInMinutes, workingHoursStart and workingHourEnd.
Why I am returning object is because you may need the timestamp of selected slot in your further application use.
Fiddle - https://jsfiddle.net/rahulrulez/t8ezfj2q/
As the comment in the code says, you can remove the 0 before the hours if you don't want it, by removing that line.
If you don't want the end in the array just replace the <= by <in the for loop
function timeArray(start, end){
var start = start.split(":");
var end = end.split(":");
start = parseInt(start[0]) * 60 + parseInt(start[1]);
end = parseInt(end[0]) * 60 + parseInt(end[1]);
var result = [];
for ( time = start; time <= end; time+=30){
result.push( timeString(time));
}
return result;
}
function timeString(time){
var hours = Math.floor(time / 60);
var minutes = time % 60;
if (hours < 10) hours = "0" + hours; //optional
if (minutes < 10) minutes = "0" + minutes;
return hours + ":" + minutes;
}
console.log(timeArray("7:30", "12:00"));
A shorter version:
timeArray = [];
....
let i = 0;
let hour = 8;
let odd: boolean;
do {
odd = false;
if (i % 2 === 0) {
odd = true;
hour--;
}
this.timeArray.push(hour.toString() + (odd ? ":30" : ":00"));
i++;
hour++;
} while (i < 12);
....
Demo
I have two HTML input boxes, that need to calculate the time difference in JavaScript onBlur (since I need it in real time) and insert the result to new input box.
Format example: 10:00 & 12:30 need to give me: 02:30
Thanks!
Here is one possible solution:
function diff(start, end) {
start = start.split(":");
end = end.split(":");
var startDate = new Date(0, 0, 0, start[0], start[1], 0);
var endDate = new Date(0, 0, 0, end[0], end[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = Math.floor(diff / 1000 / 60 / 60);
diff -= hours * 1000 * 60 * 60;
var minutes = Math.floor(diff / 1000 / 60);
// If using time pickers with 24 hours format, add the below line get exact hours
if (hours < 0)
hours = hours + 24;
return (hours <= 9 ? "0" : "") + hours + ":" + (minutes <= 9 ? "0" : "") + minutes;
}
DEMO: http://jsfiddle.net/KQQqp/
Try This
var dif = ( new Date("1970-1-1 " + end-time) - new Date("1970-1-1 " + start-time) ) / 1000 / 60 / 60;
tl;dr
One off run
const t1 = new Date(1579876543210) // your initial time
const t2 = new Date(1579987654321) // your later time
const diff = t2-t1
const SEC = 1000, MIN = 60 * SEC, HRS = 60 * MIN
const humanDiff = `${Math.floor(diff/HRS)}:${Math.floor((diff%HRS)/MIN).toLocaleString('en-US', {minimumIntegerDigits: 2})}:${Math.floor((diff%MIN)/SEC).toLocaleString('en-US', {minimumIntegerDigits: 2})}.${Math.floor(diff % SEC).toLocaleString('en-US', {minimumIntegerDigits: 4, useGrouping: false})}`
console.log("humanDiff:", humanDiff)
// > humanDiff: 30:51:51.0111
As a function
function humanDiff (t1, t2) {
const diff = Math.max(t1,t2) - Math.min(t1,t2)
const SEC = 1000, MIN = 60 * SEC, HRS = 60 * MIN
const hrs = Math.floor(diff/HRS)
const min = Math.floor((diff%HRS)/MIN).toLocaleString('en-US', {minimumIntegerDigits: 2})
const sec = Math.floor((diff%MIN)/SEC).toLocaleString('en-US', {minimumIntegerDigits: 2})
const ms = Math.floor(diff % SEC).toLocaleString('en-US', {minimumIntegerDigits: 4, useGrouping: false})
return `${hrs}:${min}:${sec}.${ms}`
}
const t1 = new Date(1579876543210)
const t2 = new Date(1579987654321)
console.log("humanDiff(t1, t2):", humanDiff(t1, t2))
// > humanDiff: 30:51:51.0111
Explanation
Adjust humanDiff for your maximum and minimum reportable increments and formatting needs:
const t1 = new Date(1579876543210) // Set your initial time (`t1`)
const t2 = new Date(1579986654321) // , conclusion time (`t2`), and
const diff = t2-t1 // calculate their difference in milliseconds
console.log(" t2:", t2.toISOString()) // > t2: 2020-01-25T21:27:34.321Z
console.log(" t1:", t1.toISOString()) // > t1: 2020-01-24T14:35:43.210Z
console.log(" diff:", diff) // > diff: 111111111
// Set your constant time values for easy readability
const SEC = 1000
const MIN = 60 * SEC
const HRS = 60 * MIN
/* For a given unit
1) disregard any previously relevant units, e.g. to calculate minutes, we can
disregard all hours & focus on only the remainder - `(diff%HRS)`
2) divide the remainder by the given unit, e.g. for minutes, `(diff%HRS)/MIN`
3) disregard any remainder, e.g. again for minutes, `Math.floor((diff%HRS)/MIN)`
NOTE: for your maximum unit (HRS in the examples below) you probably _don't_
want to disregard high values, e.g. If the difference is >24 hrs and something,
you should either include a DAYS value, or simply display 30 hrs */
let hrs = Math.floor(diff/HRS)
let min = Math.floor((diff%HRS)/MIN)
let sec = Math.floor((diff%MIN)/SEC)
let ms = Math.floor(diff % SEC) // just the remainder
// BUT ms IS NOT ACTUALLY CORRECT, see humanDiff_3 for the fix ;-)
let humanDiff_1 = `${hrs}:${min}:${sec}.${ms}`
console.log("humanDiff_1:", humanDiff_1)
// > humanDiff_1: 30:51:51.111
sec = Math.round((diff%MIN)/SEC) // can also just round the last unit
const humanDiff_2 = `${hrs} hrs ${min} mins & ${sec} secs`
console.log("humanDiff_2:", humanDiff_2)
// > humanDiff_2: 30 hrs 51 mins & 51 secs
/* To ensure a set number of digits, format the numbers with `toLocaleString`'s
`minimumIntegerDigits`, if more than 3 digits, also use its `useGrouping` */
hrs = Math.floor(diff/HRS)
min = Math.floor((diff%HRS)/MIN).toLocaleString('en-US', {minimumIntegerDigits: 2})
sec = Math.floor((diff%MIN)/SEC).toLocaleString('en-US', {minimumIntegerDigits: 2})
ms = Math.floor(diff % SEC).toLocaleString('en-US', {minimumIntegerDigits: 4, useGrouping: false})
const humanDiff_3 = `${hrs}:${min}:${sec}.${ms}`
console.log("humanDiff_3:", humanDiff_3)
// > humanDiff_3: 30:51:51.0111
// NOTE: milliseconds are now 4 digits
This solution works for calculating diff between to separate military times
Example format: start = 23:00 / end = 02:30
function diff(start, end) {
start = start.split(":");
end = end.split(":");
if(Number(start[0]) > Number(end[0]) ) {
var num = Number(start[0])
var countTo = Number(end[0]);
var count = 0;
for (var i = 1; num != countTo;) {
num = num + i
if(num > 24) {
num = 0
}
count++
}
var hours = count - 1;
var startDate = new Date(0, 0, 0, start[0], start[1], 0);
var endDate = new Date(0, 0, 0, end[0], end[1], 0);
if(startDate.getMinutes() > endDate.getMinutes()) {
var hours = count - 2;
var diff = 60 - (startDate.getMinutes() - endDate.getMinutes());
} else {
var diff = endDate.getMinutes() - startDate.getMinutes();
}
var minutes = diff
} else {
var startDate = new Date(0, 0, 0, start[0], start[1], 0);
var endDate = new Date(0, 0, 0, end[0], end[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = Math.floor(diff / 1000 / 60 / 60);
diff -= hours * 1000 * 60 * 60;
var minutes = Math.floor(diff / 1000 / 60);
}
var returnValue = (hours < 9 ? "0" : "") + hours + ":" + (minutes < 9 ? "0" : "") + minutes
return returnValue;
}
Well this work almost great. Now use this code to calculate: 23:50 - 00:10 And see what you get.Or even 23:30 - 01:30. That's a mess.
Because getting the answer the other way in php is:
$date1 = strtotime($_POST['started']);
$date2 = strtotime($_POST['ended']);
$interval = $date2 - $date1;
$playedtime = $interval / 60;
But still, it works like yours.
I guess have to bring in the dates aswell?
And again: My hard research and development helped me.
if (isset($_POST['calculate'])) {
$d1 = $_POST['started'];
$d2 = $_POST['ended'];
if ($d2 < $d1) {
$date22 = date('Y-m-');
$date222 = date('d')-1;
$date2 = $date22."".$date222;
} else {
$date2 = date('Y-m-d');
}
$date1 = date('Y-m-d');
$start_time = strtotime($date2.' '.$d1);
$end_time = strtotime($date1.' '.$d2); // or use date('Y-m-d H:i:s') for current time
$playedtime = round(abs($start_time - $end_time) / 60,2);
}
And that's how you calculate time over to the next day.
//edit. First i had date1 jnd date2 switched. I need to -1 because this calculation only comes on next day and the first date vas yesterday.
After improving and a lot of brain power with my friend we came up to this:
$begin=mktime(substr($_GET["start"], 0,2),substr($_GET["start"], 2,2),0,1,2,2003);
$end=mktime(substr($_GET["end"], 0,2),substr($_GET["end"], 2,2),0,1,3,2003);
$outcome=($end-$begin)-date("Z");
$minutes=date("i",$outcome)+date("H",$outcome)*60; //Echo minutes only
$hours = date("H:i", $outcome); //Echo time in hours + minutes like 01:10 or something.
So you actually need only 4 lines of code to get your result. You can take only minutes or show full time (like difference is 02:32) 2 hours and 32 minutes.
What's most important: Still you can calculate overnight in 24 hour clock aka: Start time 11:50PM to let's say 01:00 AM (in 24 hour clock 23:50 - 01:00) because in 12 hour mode it works anyway.
What's most important: You don't have to format your input. You can use just plain 2300 as 23:00 input. This script will convert text field input to correct format by itself.
Last script uses standard html form with method="get" but you can convert it to use POST method as well.
This is an updated version of one that was already submitted. It is with the seconds.
function diff(start, end) {
start = start.split(":");
end = end.split(":");
var startDate = new Date(0, 0, 0, start[0], start[1], 0);
var endDate = new Date(0, 0, 0, end[0], end[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = Math.floor(diff / 1000 / 60 / 60);
diff -= hours * (1000 * 60 * 60);
var minutes = Math.floor(diff / 1000 / 60);
diff -= minutes * (1000 * 60);
var seconds = Math.floor(diff / 1000);
// If using time pickers with 24 hours format, add the below line get exact hours
if (hours < 0)
hours = hours + 24;
return (hours <= 9 ? "0" : "") + hours + ":" + (minutes <= 9 ? "0" : "") + minutes + (seconds<= 9 ? "0" : "") + seconds;
}
My Updated Version:
Allows for you to convert the dates into milliseconds and go off of that instead of splitting.
Example Does -- Years/Months/Weeks/Days/Hours/Minutes/Seconds
Example: https://jsfiddle.net/jff7ncyk/308/
With seconds you provided is not get result to me please find my updated function giving you the correct seconds here - By Dinesh J
function diff(start, end) {
start = start.split(":");
end = end.split(":");
var startDate = new Date(0, 0, 0, start[0], start[1],start[2], 0);
var endDate = new Date(0, 0, 0, end[0], end[1],end[2], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = Math.floor(diff / 1000 / 60 / 60);
diff -= hours * 1000 * 60 * 60;
var minutes = Math.floor(diff / 1000 / 60);
var seconds = Math.floor(diff / 1000)-120;
// If using time pickers with 24 hours format, add the below line get exact hours
if (hours < 0)
hours = hours + 24;
return (hours <= 9 ? "0" : "") + hours + ":" + (minutes <= 9 ? "0" : "") + minutes+ ":" + (seconds <= 9 ? "0" : "") + seconds;
}
Depending on what you allow to enter, this one will work. There may be some boundary issues if you want to allow 1am to 1pm
NOTE: This is NOT using a date objects or moment.js
function pad(num) {
return ("0"+num).slice(-2);
}
function diffTime(start,end) {
var s = start.split(":"), sMin = +s[1] + s[0]*60,
e = end.split(":"), eMin = +e[1] + e[0]*60,
diff = eMin-sMin;
if (diff<0) { sMin-=12*60; diff = eMin-sMin }
var h = Math.floor(diff / 60),
m = diff % 60;
return "" + pad(h) + ":" + pad(m);
}
document.getElementById('button').onclick=function() {
document.getElementById('delay').value=diffTime(
document.getElementById('timeOfCall').value,
document.getElementById('timeOfResponse').value
);
}
<input type="time" id="timeOfCall">
<input type="time" id="timeOfResponse">
<button type="button" id="button">CLICK</button>
<input type="time" id="delay">
calTimeDifference(){
this.start = dailyattendance.InTime.split(":");
this.end = dailyattendance.OutTime.split(":");
var time1 = ((parseInt(this.start[0]) * 60) + parseInt(this.start[1]))
var time2 = ((parseInt(this.end[0]) * 60) + parseInt(this.end[1]));
var time3 = ((time2 - time1) / 60);
var timeHr = parseInt(""+time3);
var timeMin = ((time2 - time1) % 60);
}
TimeCount = function()
{
t++;
var ms = t;
if (ms == 99)
{
s++;
t = 0;
if ( s == 60)
{
m++;
s = 0;
}
}
Dis_ms = checkTime(ms);
Dis_s = checkTime(s);
Dis_m = checkTime(m);
document.getElementById("time_val").innerHTML = Dis_m + ":" + Dis_s+ ":" + Dis_ms;
}
function checkTime(i)
{
if (i<10) {
i = "0" + i;
}
return i;
}
Try this: actually this a problem from codeeval.com
I solved it in this way .
This program takes a file as the argument so i used a little node js to read the file.
Here is my code.
var fs = require("fs");
fs.readFileSync(process.argv[2]).toString().split('\n').forEach(function (line) {
if (line !== "") {
var arr = line.split(" ");
var arr1 = arr[0].split(":");
var arr2 = arr[1].split(":");
var time1 = parseInt(arr1[0])*3600 + parseInt(arr1[1])*60 + parseInt(arr1[2]);
var time2 = parseInt(arr2[0])*3600 + parseInt(arr2[1])*60 + parseInt(arr2[2]);
var dif = Math.max(time1,time2) - Math.min(time1,time2);
var ans = [];
ans[0] = Math.floor(dif/3600);
if(ans[0]<10){ans[0] = "0"+ans[0]}
dif = dif%3600;
ans[1] = Math.floor(dif/60);
if(ans[1]<10){ans[1] = "0"+ans[1]}
ans[2] = dif%60;
if(ans[2]<10){ans[2] = "0"+ans[2]}
console.log(ans.join(":"));
}
});
We generally need time difference to estimate time taken by I/O operations, SP call etc, the simplest solution for NodeJs (the console is in callback- async execution) is following:
var startTime = new Date().getTime();
//This will give you current time in milliseconds since 1970-01-01
callYourExpectedFunction(param1, param2, function(err, result){
var endTime = new Date().getTime();
//This will give you current time in milliseconds since 1970-01-01
console.log(endTime - startTime)
//This will give you time taken in milliseconds by your function
if(err){
}
else{
}
})
For example:
Given time: 08:22 => Rounded to: 08:15
Given time: 08:23 => Rounded to: 08:30
Should be pretty simple. But all I was able to produce is lengthy, not very good code to solve the issue. My mind's just gone blank.
Regards
Given that you have hours and minutes in variables (if you don't you can get them from the Date instance anyway by using Date instance functions):
var m = (parseInt((minutes + 7.5)/15) * 15) % 60;
var h = minutes > 52 ? (hours === 23 ? 0 : ++hours) : hours;
minutes can as well be calculated by using Math.round():
var m = (Math.round(minutes/15) * 15) % 60;
or doing it in a more javascript-sophisticated expression without any functions:
var m = (((minutes + 7.5)/15 | 0) * 15) % 60;
var h = ((((minutes/105) + .5) | 0) + hours) % 24;
You can check the jsPerf test that shows Math.round() is the slowest of the three while mainly the last one being the fastest as it's just an expression without any function calls (no function call overhead i.e. stack manipulation, although native functions may be treated differently in Javascript VM).
//----
This function round the time to the nearest quarter hour.
function roundTimeQuarterHour(time) {
var timeToReturn = new Date(time);
timeToReturn.setMilliseconds(Math.round(timeToReturn.getMilliseconds() / 1000) * 1000);
timeToReturn.setSeconds(Math.round(timeToReturn.getSeconds() / 60) * 60);
timeToReturn.setMinutes(Math.round(timeToReturn.getMinutes() / 15) * 15);
return timeToReturn;
}
With Time String
Here is a method that will round a time string like the one you presented. Eg "08:22"
let roundTime = (time, minutesToRound) => {
let [hours, minutes] = time.split(':');
hours = parseInt(hours);
minutes = parseInt(minutes);
// Convert hours and minutes to time in minutes
time = (hours * 60) + minutes;
let rounded = Math.round(time / minutesToRound) * minutesToRound;
let rHr = ''+Math.floor(rounded / 60)
let rMin = ''+ rounded % 60
return rHr.padStart(2, '0')+':'+rMin.padStart(2, '0')
}
// USAGE //
// Round time to 15 minutes
roundTime('8:07', 15); // "08:00"
roundTime('7:53', 15); // "08:00"
roundTime('7:52', 15); // "07:45"
With Hours and Minutes Already Split Up
You can use this method if you don't need to parse out the hour and minute strings like your example shows
let roundTime = (hours, minutes, minutesToRound) => {
// Convert hours and minutes to minutes
time = (hours * 60) + minutes;
let rounded = Math.round(time / minutesToRound) * minutesToRound;
let roundedHours = Math.floor(rounded / 60)
let roundedMinutes = rounded % 60
return { hours: roundedHours, minutes: roundedMinutes }
}
// USAGE //
// Round time to 15 minutes
roundTime(7, 52, 15); // {hours: 7, minutes: 45}
roundTime(7, 53, 15); // {hours: 8, minutes: 0}
roundTime(1, 10, 15); // {hours: 1, minutes: 15}
With Existing Date Object
Or, if you are looking to round an already existing date object to the nearest x minutes, you can use this method.
If you don't give it any date it will round the current time. In your case, you can round to the nearest 15 minutes.
let getRoundedDate = (minutes, d=new Date()) => {
let ms = 1000 * 60 * minutes; // convert minutes to ms
let roundedDate = new Date(Math.round(d.getTime() / ms) * ms);
return roundedDate
}
// USAGE //
// Round existing date to 5 minutes
getRoundedDate(15, new Date()); // 2018-01-26T00:45:00.000Z
// Get current time rounded to 30 minutes
getRoundedDate(30); // 2018-01-26T00:30:00.000Z
The code here is a little verbose but I'm sure you'll see how you could combine the lines to make this shorter. I've left it this way to clearly show the steps:
var now = new Date();
var mins = now.getMinutes();
var quarterHours = Math.round(mins/15);
if (quarterHours == 4)
{
now.setHours(now.getHours()+1);
}
var rounded = (quarterHours*15)%60;
now.setMinutes(rounded);
document.write(now);
Divide by 9e5 milliseconds (15 * 60 * 1000), round, and multiply back by 9e5 :
const roundToQuarter = date => new Date(Math.round(date / 9e5) * 9e5)
console.log( roundToQuarter(new Date("1999-12-31T23:52:29.999Z")) ) // 1999-12-31T23:45:00
console.log( roundToQuarter(new Date("1999-12-31T23:52:30.000Z")) ) // 2000-01-01T00:00:00
console.log( roundToQuarter(new Date) )
I use these code:
function RoundUp(intervalMilliseconds, datetime){
datetime = datetime || new Date();
var modTicks = datetime.getTime() % intervalMilliseconds;
var delta = modTicks === 0 ? 0 : datetime.getTime() - modTicks;
delta += intervalMilliseconds;
return new Date(delta);
}
function RoundDown(intervalMilliseconds, datetime){
datetime = datetime || new Date();
var modTicks = datetime.getTime() % intervalMilliseconds;
var delta = modTicks === 0 ? 0 : datetime.getTime() - modTicks;
return new Date(delta);
}
function Round(intervalMilliseconds, datetime){
datetime = datetime || new Date();
var modTicks = datetime.getTime() % intervalMilliseconds;
var delta = modTicks === 0 ? 0 : datetime.getTime() - modTicks;
var shouldRoundUp = modTicks > intervalMilliseconds/2;
delta += shouldRoundUp ? intervalMilliseconds : 0;
return new Date(delta);
}
Round to the nearest 5 minutes:
//with current datetime
var result = Round(5 * 60 * 1000);
//with a given datetime
var dt = new Date();
var result = Round(5 * 60 * 1000, dt);
There is an NPM package #qc/date-round that can be used. Given that you have a Date instance to be rounded
import { round } from '#qc/date-round'
const dateIn = ...; // The date to be rounded
const interval = 15 * 60 * 1000; // 15 minutes (aka quarter hour)
const dateOut = round(dateIn, interval)
Then you can use date-fns to format the date
import format from 'date-fns/format';
console.log(format(dateOut, 'HH:mm')) // 24-hr
console.log(format(dateOut, 'hh:mm a')) // 12-hr
Another one with date-fns (not mandatory)
import {getMinutes, setMinutes, setSeconds, setMilliseconds} from 'date-fns'
let date = new Date();
let min = getMinutes(date);
let interval = 3 // in minutes
let new_min = min - min%interval + interval;
let new_date = setMilliseconds(setSeconds(setMinutes(date,new_min),0),0)
console.log('Orignal Date : ' + date);
console.log('Original Minute : ' + min);
console.log('New Minute : ' + new_min);
console.log('New Date : ' + new_date);
Pass the interval in milliseconds get the next cycle in roundUp order
Example if I want next 15 minute cycle from current time then call this method like *calculateNextCycle(15 * 60 * 1000);*
Samething for quarter hour pass the interval
function calculateNextCycle(interval) {
const timeStampCurrentOrOldDate = Date.now();
const timeStampStartOfDay = new Date().setHours(0, 0, 0, 0);
const timeDiff = timeStampCurrentOrOldDate - timeStampStartOfDay;
const mod = Math.ceil(timeDiff / interval);
return new Date(timeStampStartOfDay + (mod * interval));
}
console.log(calculateNextCycle(15 * 60 * 1000));
This method is specifically for Vue.js, it takes a time, and returns to the nearest entered increment, I based this on an above answer, but this is for Vue specifically using echma-6 standards. It will return T:06:00:00, if you fed 06:05 into it. This is used specifically with vuetify's v-calendar to choose a time in weeklyor daily format.
This answer also adds the 0 for like 06 hrs. Which is where this differs from the above answers. If you change the 30 to 15
methods: {
roundTimeAndFormat(datetime, roundTo) {
const hrsMins = datetime.split(':')
let min = ((((hrsMins[1] + 7.5) / roundTo) | 0) * roundTo) % 60
let hr = (((hrsMins[1] / 105 + 0.5) | 0) + hrsMins[0]) % 24
if (Number(hr) < 10) {
hr = ('0' + hr).slice(-2)
}
if (min === 0) {
min = ('0' + min).slice(-2)
}
return 'T' + hr + ':' + min + ':00'
}
}
You would just call:
this.roundTimeAndFormat(dateTime, 15)
And you would get the time to the nearest 15min interval.
If you enter, 11:01, you'd get T11:00:00
Might help others. For any language. Mainly trick with round function.
roundedMinutes = yourRoundFun(Minutes / interval) * interval
E.g. The interval could be 5 minutes, 10 minutes, 15 minutes, 30 minutes.
Then rounded minutes can be reset to the respective date.
yourDateObj.setMinutes(0)
yourDateObj.setMinutes(roundedMinutes)
also if required then
yourDateObj.setSeconds(0)
yourDateObj.setMilliSeconds(0)
Simple?