Calculate duration by start and end hour - javascript

I have this json :
{
endTime: "14:00:00"
startTime: "12:00:00"
}
I need to calculate duration, so I did like this :
let duration = endTime.slice(0, -3) - startTime.slice(0, -3);
But not working as expected. I have a js error : left-hand must be type number
Have an idea about that ?
Thx in advance.

Ok, I'm considering you are only receiving an object with endTime and startTime properties and not working with arrays.
In the following code block, you can transform your strings into dates and do calcs with them. In this example, I just subtracted endDate - startDate to get the difference in milliseconds and then I converted to seconds, minutes and hours.
const data = {
endTime: '14:00:00',
startTime: '12:00:00',
}
// separates the string in hours, minutes and seconds
const [startHours, startMinutes, startSeconds] = data.startTime.split(':')
const [endHours, endMinutes, endSeconds] = data.endTime.split(':')
// creates a Date instance to work with
const startDate = new Date()
const endDate = new Date()
// sets hour, minutes and seconds to startDate
startDate.setHours(startHours)
startDate.setMinutes(startMinutes)
startDate.setSeconds(startSeconds)
// sets hour, minutes and seconds to endDate
endDate.setHours(endHours)
endDate.setMinutes(endMinutes)
endDate.setSeconds(endSeconds)
const differenceInMilliseconds = endDate - startDate
const differenceInSeconds = differenceInMilliseconds / 1000
const differenceInMinutes = differenceInSeconds / 60
const differenceInHours = differenceInMinutes / 60
console.log(differenceInHours) // outputs 2 hours

Too many ways to do that, this is one of the simple ways.
Cast the time to a Date object, then get their timestamp (ms), finally get the duration:
const startTimeTs = new Date(`2021-04-01 ${startTime}`).valueOf();
const endTimeTs = new Date(`2021-04-01 ${endTime}`).valueOf();
const durationTs = endTimeTs - startTimeTs;
const durationInSecondes = durationTs / 1000;
const durationInMinutes = durationInSecondes / 60;
const durationInHours = durationInMinutes / 60;

const json = {
endTime: "14:00:00",
startTime: "12:00:00"
};
const start = new Date(2000, 3, 3, ...(json.startTime.split(':').map( x => Number(x))));
const end = new Date(2000, 3, 3, ...(json.endTime.split(':').map( x => Number(x))));
const output = document.getElementById('output');
output.textContent = ((end-start)*0.001)+ ' seconds difference';
<div id="output"></div>

There to many ways to do it, but if you need in same format as you got in json you can use something like it
const data = {
endTime: "14:00:00",
startTime: "12:00:00"
};
const { endTime, startTime } = data;
const endTimeArr = endTime.split(':').map(el => +el);
const startTimeArr = startTime.split(':').map(el => +el);
const resArr = endTimeArr.map((el, i) => el - startTimeArr[i]);
const res = resArr.join(':');

You can do it like this:
let times = {
endTime: "14:00",
startTime: "12:00:00"
};
function calculate(obj) {
let startTime = obj.startTime;
let endTime = obj.endTime;
let sum = new Date(parseInt(endTime)) - new Date(parseInt(startTime));
return sum;
}
console.log(calculate(times));

Convert the HH:MM:SS to seconds.
Subtract the two values - you get the seconds of duration.
Convert the seconds to HH:MM:SS.
/* helper functions */
const format = n =>
String(n).padStart(2, 0);
const time2seconds = time => {
const [hours, minutes, seconds] = time.split(":").map(Number);
return seconds + minutes * 60 + hours * 60 * 60;
}
const seconds2time = seconds => {
const hours = format(Math.floor(seconds / (60 * 60)));
const minutes = format(Math.floor(seconds / 60) % 60);
seconds = format(seconds % 60);
return `${hours}:${minutes}:${seconds}`;
}
/* /helper functions */
const toDuration = ({startTime, endTime}) =>
seconds2time(time2seconds(endTime) - time2seconds(startTime));
test({
endTime: "14:00:00",
startTime: "12:00:00"
})
test({
endTime: "15:30:00",
startTime: "11:00:00"
})
test({
endTime: "18:24:05",
startTime: "11:47:12"
})
function test(obj) {
const result = toDuration(obj);
console.log(`duration between ${obj.startTime} and ${obj.endTime} is: ${result}`);
}

Related

Time difference in hh:mm format

I am calculating the difference between two times with the following function:
const calcTimeDiff = (time1: string, time2: string) => {
const timeStart = new Date()
const timeEnd = new Date()
const valueStart = time1.split(':')
const valueEnd = time2.split(':')
timeStart.setHours(+valueStart[0], +valueStart[1], 0, 0)
timeEnd.setHours(+valueEnd[0], +valueEnd[1], 0, 0)
const difference = timeEnd.getTime() - timeStart.getTime()
return format(difference, 'HH:mm') // date-fns
}
For example calcTimeDiff('08:45', '16:00') which should yield 07:15. However, I get 08:15 instead. My guess is that it is caused by timezone conflicts.
Debugging my code gave me the following insights:
console.log(difference, timeStart, timeEnd)
Thu Jan 01 1970 08:15:00 GMT+0100, Wed Aug 17 2022 08:45:00 GMT+0200, Wed Aug 17 2022 16:00:00 GMT+0200
Why not make use of the intervalToDuration method which is included in the date-fns library. This will return an object for you like below
{years: 0, months: 0, days: 0, hours...}
It can be implemented easily into your function like so:
const calcTimeDiff = (time1: string, time2: string) => {
const timeStart = new Date()
const timeEnd = new Date()
const valueStart = time1.split(':')
const valueEnd = time2.split(':')
timeStart.setHours(+valueStart[0], +valueStart[1], 0, 0)
timeEnd.setHours(+valueEnd[0], +valueEnd[1], 0, 0)
return intervalToDuration({ start: timeStart, end: timeEnd })
}
If you get string in hh:mm format, you don't need Date, just calculate:
const calcTimeDiff = (time1: string, time2: string) => {
const [h1, m1] = time1.split(':');
const [h2, m2] = time2.split(':');
let diff = (h2 - h1) * 60 + (m2 - m1);
if (diff < 0) diff += 24 * 60;
const hours = Math.floor(diff / 60);
const minutes = diff - hours * 60;
const hh = hours.toString().padStart(2, '0');
const mm = minutes.toString().padStart(2, '0');
return `${hh}:${mm}`;
}
I agree with #eugene anf thats the right way to go but in case you are looking for an answer in the format your code is written here is the code
const calcTimeDiff = (time1, time2) => {
const timeStart = new Date()
const timeEnd = new Date()
const valueStart = time1.split(':')
const valueEnd = time2.split(':')
timeStart.setHours(+valueStart[0], +valueStart[1], 0, 0)
timeEnd.setHours(+valueEnd[0], +valueEnd[1], 0, 0)
let difference = new Date();
difference.setHours(timeEnd.getHours() - timeStart.getHours())
difference.setMinutes(timeEnd.getMinutes() - timeStart.getMinutes())
return console.log(difference, timeStart, timeEnd) // date-fns
}
calcTimeDiff('08:45', '16:00');
In your code you are creating a date object using the difference in time which will lead you to a random time.
Solved it this way:
const calcTimeDiff = (time1: string, time2: string) => {
const timeStart = new Date()
const timeEnd = new Date()
const valueStart = time1.split(':')
const valueEnd = time2.split(':')
timeStart.setHours(+valueStart[0], +valueStart[1], 0, 0)
timeEnd.setHours(+valueEnd[0], +valueEnd[1], 0, 0)
const difference = new Date(timeEnd.getTime() - timeStart.getTime())
return format(
addMinutes(difference, difference.getTimezoneOffset()),
'HH:mm'
)
}
You can use moment.js to perform what you want.
This can be done using the diff method.
const calcTimeDiff = (time1, time2) => {
const start = moment(time1, 'HH:mm');
const end = moment(time2, 'HH:mm');
let diff = end.diff(start);
return moment.utc(diff).format("HH:mm");
}
console.log(calcTimeDiff("8:15", "16:15"))
console.log(calcTimeDiff("7:45", "19:21"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

I want to add 15 minutes slot to each StartTime in a loop and store in array of objects

const createTimeSlots=(fromTime,toTime)=>{
I want to add 15 minutes slot to each StartTime in a loop and store in array of objects.
Assuming the inputs are in timestamp, add 15 mins equivalent of timestamps and push that timestamp(or push mins/hrs etc.). Here's the code example where start time is current timestamp and endtime is current + 3hrs in timestamp.
function createSlots(start, end) {
let slots = [];
const mins = 15 * 60 * 1000; // 15 mins
const date = (dt) => new Date(dt);
while (start <= end) {
start += mins;
// only mins
//slots.push(date(start).getMinutes());
// hrs + mins
slots.push(`${date(start).getHours()}:${date(start).getMinutes()}`);
}
return slots;
}
var slots = createSlots(Date.now(), Date.now() + 3 * 3600 * 1000); // from (now) to (now + 3hrs)
console.log("slots : ", slots);
Let's assume inputs are valid date-time format.
This solution will work across dates, let's say you give the start time today and end time tomorrow then also it will work without any issue.
const createTimeSlots = (fromTime, toTime, slotLength =15*60) => {
let slotStart = new Date(fromTime).valueOf();
let slotEnd = new Date(fromTime).valueOf() + slotLength * 1000;
let endEpoch = new Date(toTime).valueOf();
let ob = [];
for (slotEnd; slotEnd <= endEpoch; slotEnd = slotEnd + slotLength * 1000) {
ob.push({
'from': formatDate(slotStart),
'to': formatDate(slotEnd)
});
slotStart = slotEnd;
}
return ob;
}
function formatDate(epoch) {
let d = new Date(epoch);
let month = String((d.getMonth() + 1)).padStart(2, '0');
let day = String((d.getDate())).padStart(2, '0');
let hours = String((d.getHours())).padStart(2, '0');
let mins = String((d.getMinutes())).padStart(2, '0');
return `${d.getFullYear()}-${month}-${day} ${hours}:${mins}`;
}
const from = "2022-05-25 23:00";
const to = "2022-05-26 01:00";
const slotLength = 15 * 60; //seconds
var r = createTimeSlots(from, to, slotLength );
console.log(r);

Convert string to time and add 2 hours in JS

i get this time from an external JSON :
"time":"19:45"
I need to add 2 hours from this string.
Is it possible in JS?
Thanks
Try this
let myTime = '19:45'
function getTime(time, addHour) {
let [h, m] = time.split(':');
let date = new Date();
date.setHours(h, m, 0)
date.toString();
let res = `${date.getHours()+addHour}:${date.getMinutes()}`
return res
}
console.log(getTime( myTime, 2 ))
uses String.split to get hourNum and minuteNum, then construct one Date object and uses setTime to add two hours.
function addHours(text, hours=2) {
const [hourNum, minNum] = text.split(':')
const time = new Date(0, 0, 0, hourNum, minNum)
time.setTime(time.getTime() + (hours * 60 * 60 * 1000))
return `${time.getHours()}:${time.getMinutes()}`
}
console.log(addHours('19:45', 2))
console.log(addHours('23:45', 2))
A Date object isn't necessary to do time mathematics, it just means taking account of minutes and seconds (60) and maybe days (24).
E.g.
// Add time to a timestamp, both in in HH:mm format
// If respectDay is true, hours are % 24
function addTime(start, increment, respectDay = false) {
let pad = n => ('0' + n).slice(-2);
let timeToMins = time => time.split(':').reduce((h, m) => h*60 + m*1);
let minsToTime = (mins, respectDay = false) => `${pad((mins / 60 | 0) % (respectDay? 24 : Number.POSITIVE_INFINITY))}:${pad(mins%60)}`;
return minsToTime(timeToMins(start) + timeToMins(increment), respectDay);
}
let time = "19:45";
console.log(addTime(time, '8:23')); // Total time : 28:08
console.log(addTime(time, '8:23', true)); // As day time : 04:08

How to add new minutes value for every next array element?

I want to add 36 minutes for every next value in the array but I get only one increase for all elements in array how to implement an algorithm which I describe above
let timestamps = [
"2020-01-21T22:36:00.000Z",
"2020-01-21T23:12:00.000Z",
"2020-01-21T23:48:00.000Z",
"2020-01-22T00:24:00.000Z",
"2020-01-22T01:00:00.000Z",
]
const minutesToAdjust = 36
const millisecondsPerMinute = 60000
const oneDay = 1000 * 60 * 60 * 24
const twentyFourHours = new Date(new Date() - oneDay)
const transformTimeseriesTo24h = timestamps.map(el => {
el = new Date(twentyFourHours + (minutesToAdjust * millisecondsPerMinute))
return el
})
timestamps = transformTimeseriesTo24h
console.log(timestamps)
Using Date.parse(el)
let timestamps = [
"2020-01-21T22:36:00.000Z",
"2020-01-21T23:12:00.000Z",
"2020-01-21T23:48:00.000Z",
"2020-01-22T00:24:00.000Z",
"2020-01-22T01:00:00.000Z",
]
const minutesToAdjust = 36
const millisecondsPerMinute = 60000
const oneDay = 1000 * 60 * 60 * 24
const twentyFourHours = new Date(new Date() - oneDay)
const transformTimeseriesTo24h = timestamps.map(el => {
return new Date(Date.parse(el) + (minutesToAdjust * millisecondsPerMinute))
})
timestamps = transformTimeseriesTo24h
console.log(timestamps)
Your code is ignoring the original dates by immediately assigning to el. Instead, since they're valid ISO-8601 date/time strings, parse them then add 36 minutes to them:
timestamps = timestamps.map(el => {
const dt = new Date(el);
dt.setMinutes(dt.getMinutes() + 36); // Will wrap for you
return dt; // Or `return dt.toISOString();`
});
Live Example:
let timestamps = [
"2020-01-21T22:36:00.000Z",
"2020-01-21T23:12:00.000Z",
"2020-01-21T23:48:00.000Z",
"2020-01-22T00:24:00.000Z",
"2020-01-22T01:00:00.000Z",
];
timestamps = timestamps.map(el => {
const dt = new Date(el);
dt.setMinutes(dt.getMinutes() + 36); // Will wrap for you
return dt; // Or `return dt.toISOString();`
});
console.log(timestamps);
Or... "Every next value" sounds like you want to add 0 to the first one, 36 minutes to the second one, 72 (36 * 2) minutes to the third, ...? If so, you can use the index that map passes as the second argument:
timestamps = timestamps.map((el, index) => {
const dt = new Date(el);
dt.setMinutes(dt.getMinutes() + (index * 36)); // Will wrap for you
return dt; // Or `return dt.toISOString();`
});
Live Example:
let timestamps = [
"2020-01-21T22:36:00.000Z",
"2020-01-21T23:12:00.000Z",
"2020-01-21T23:48:00.000Z",
"2020-01-22T00:24:00.000Z",
"2020-01-22T01:00:00.000Z",
];
timestamps = timestamps.map((el, index) => {
const dt = new Date(el);
dt.setMinutes(dt.getMinutes() + (index * 36)); // Will wrap for you
return dt; // Or `return dt.toISOString();`
});
console.log(timestamps);
I couldn't tell whether you wanted to end up with Date instances of ISO strings. The above result in Date instances. If you want ISO strings instead, just call toISOString() on dt when returning it (see comments above).
You need to use timestamp value from array and add your offset in that
let timestamps = [
"2020-01-21T22:36:00.000Z",
"2020-01-21T23:12:00.000Z",
"2020-01-21T23:48:00.000Z",
"2020-01-22T00:24:00.000Z",
"2020-01-22T01:00:00.000Z",
];
const minutesToAdjust = 36
const millisecondsPerMinute = 60000
const oneDay = 1000 * 60 * 60 * 24
const twentyFourHours = new Date(new Date() - oneDay)
timestamps = timestamps.map(time => new Date(new Date(time).getTime() + minutesToAdjust * millisecondsPerMinute));
console.log(timestamps)
I would convert your time stamps to Unix time add the 36*60 seconds to it, and convert it back to your format.

Sum of to times using javascript

can anyone tell me how to do sum of two time using javascript (momentjs) for exemple the sum of:
2:44:56 and 2:50:56
i tried that but doesnt work:
2:44:56 + 2:50:56
any suggestions please??
Momentjs has a duration object that can be used to add or subtract two or more timespans.
const a = moment.duration('02:44:56');
const b = moment.duration('02:50:56');
const c = a.add(b);
console.log(c.hours() );
console.log(c.minutes() );
console.log(c.seconds() );
One could add the seconds, then calculate the carry value and add that to the sum of minutes and so on. That can be easily done with reduce:
function sum(date1, date2){
date1 = date1.split(":");
date2 = date2.split(":");
const result = [];
date1.reduceRight((carry,num, index) => {
const max = [24,60,60][index];
const add = +date2[index];
result.unshift( (+num+add+carry) % max );
return Math.floor( (+num + add + carry) / max );
},0);
return result.join(":");
}
console.log(
sum("2:44:56" , "2:50:56" )
);
Try it
You can do it like this. Use add method on moment object and pass your data.
let x = moment({
hours:'2',
minutes:'44',
seconds:'56'})
.add({
hours:'2',
minutes:'50',
seconds:'56' })
console.log(x)
or dynamically pass data
let time = {
hours: 2,
minutes:44,
seconds: 56
}
let time2 = {
hours: 2,
minutes:50,
seconds: 56
}
let y = moment(time)
.add(time2)
console.log(y)
The code:
var t1 = moment('2:44:56', 'HH:mm:ss');
var t2 = '2:50:56';
var parsed_t2 = t2.split(':') // [2, 50, 56]
var r = t1.add({
hours: parsed_t2[0], // 2
minutes: parsed_t2[1], // 50
seconds: parsed_t2[2], // 56
});
The process:
Parse the string as a moment object (helping it with defining the format we're using;
Split the time we want to add to the t1 by using the split() function effectively splitting our t2 into an array where we have [hours, minutes, seconds]
Add the the times together using the moments add() method.
Working example
moment() function takes hours, minutes, seconds as arguments and return a moment object which has a add() method that also can take hours, minutes, seconds as arguments and return total times.
Try addTimes(time1, time2)
function addTimes(time1, time2) {
let [hours1, minutes1, seconds1] = time1.split(':');
let [hours2, minutes2, seconds2] = time2.split(':');
return moment({ hours: hours1, minutes: minutes1, seconds: seconds1 })
.add({ hours: hours2, minutes: minutes2, seconds: seconds2 })
.format('h:mm:ss');
}
console.log(addTimes('2:44:56', '2:50:56'));
Good old JS solution:
var base = new Date(0);
var t1 = new Date(base);
var t2 = new Date(base);
t1.setUTCHours(2,45,50);
t2.setUTCHours(2,50,50);
var t = new Date(t1.getTime() + t2.getTime() - base.getTime());
result = t.getUTCHours() + ":" + t.getUTCMinutes() +":" + t.getUTCSeconds();
console.log(result);
Note that JS automatically converts time of the day to GMT timezone hence we need to use UTC version of time functions.

Categories