How To Get The Sum of Two Times Using Moment.js? - javascript

I want to add two times like time1 = '00:05' and time2 = '10:00'. I want the result like the following after sum: result='10:05'. I used moment for that, this is what I used:
let x = moment.duration(moment(this.time1, "hh:mm A").add(moment(this.time2, "hh:mm A")));
let result = moment.utc(x.asMilliseconds()).format('HH:mm:ss');
but I got nothing, how can I do it?

You can't add time this way with moment because you are asking it to add two times, not a time plus a duration. If you want to add ten minutes, use the add() function with a duration.
moment(this.time2, "hh:mm A").add(10, 'minutes')
More here: https://momentjs.com/docs/#/manipulating/add/
It's not really clear in your question what 00:05 PM means. That doesn't look like a valid time. Moment will interpret it as 12:05pm, but it looks like you want to interpret it as 5 minutes. (That's the only way you get 10:05 as an answer). You can do this with moment if you don't include the PM part of the string.
moment.duration('00:05')
Is a duration of five minutes. You can add this to your time with:
moment('10:00 PM', '"hh:mm A"').add(moment.duration('00:05'))
// 22:05:00
Adding two periods works but it is currently not obvious in moment, how to format it like you want. Until they add format() to durations this will have to do:
var d = moment.duration('03:10:10').add(moment.duration('01:20:30'))
moment.utc(d.as('milliseconds')).format("HH:mm:ss")
// '04:30:40'

See Example For Add & Diff using moment.js .. cheers😀
// addTimes(["01:00", "00:30", "00:50"]) ---- 02:20
addTimes(times) {
let duration = 0;
times.forEach(time => {
duration = duration + moment.duration(time).as('milliseconds')
});
return moment.utc(duration).format("HH:mm")
}
// subtractTimes(["05:00", "00:30", "00:20"]) --- 04:10
subtractTimes(times) {
let totalDiff = 0
for (let i = 0; i < times.length; i++) {
let duration = moment.duration(times[i]).as('milliseconds')
if (i == 0) {
totalDiff = duration
}
if (i > 0) {
totalDiff = totalDiff - duration
}
}
return moment.utc(totalDiff).format("HH:mm")
}

function addTwoHours(firstTime = "20:40", secondTime = "18:40") {
firstTime = firstTime.split(':');
secondTime = secondTime.split(':');
const now = moment();
const expiration = moment().add({ hour: firstTime[0], minute: firstTime[1] }).add({ hour: secondTime[0], minute: secondTime[1] });
const diff = expiration.diff(now);
const diffDuration = moment.duration(diff);
return {
"years": diffDuration.years(),
"months": diffDuration.months(),
"days": diffDuration.days(),
"hours": diffDuration.hours(),
"minutes": diffDuration.minutes(),
"yourAnswer" : `${expiration.diff(now, 'hours')}:${diffDuration.minutes()}`
}
}
console.log(addTwoHours());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

Related

Find if the given time between two times

I'm writing a code to check if the given time is between 2 passed in times. If the end time is 23:59 (i.e. 11:59 PM ) this works, but if it is 00:00, my code fails.
Here is my sample code.
const getStatus = (startTime, currentTime, EndTime) => {
var currently = currentTime.split(":")[0] * 60 + currentTime.split(":")[1];
var starting = startTime.split(":")[0] * 60 + startTime.split(":")[1];
var ending = EndTime.split(":")[0] * 60 + EndTime.split(":")[1];
return starting < currently < ending;
}
console.log(getStatus('06:00', "12:00", "18:00"));
console.log(getStatus('06:00', "12:00", "00:00"));
In reality, 12:00 PM falls between 6:00 AM and 12:00AM, but my code returns false, since, 12:00AM is coming as 00:00 as input from my system. Is there a direct way of doing it or should I replace 00:00 with 11:60 and do it?
It's not an elegant solution but if your time end time is 00:00 (midnight) you can replace it with 24:00
const normalizeTime = (time) => {
return (time === '00:00') ?
'24:00' :
time;
}
const getStatus = (startTime, currentTime, EndTime) => {
EndTime = normalizeTime(EndTime);
var currently = currentTime.split(":")[0] * 60 + currentTime.split(":")[1];
var starting = startTime.split(":")[0] * 60 + startTime.split(":")[1];
var ending = EndTime.split(":")[0] * 60 + EndTime.split(":")[1];
return starting < currently < ending;
}
console.log(getStatus('06:00', "12:00", "18:00"));
console.log(getStatus('06:00', "12:00", "00:00"));
Try this!
// 3 statuses here
// 1 -> before
// 2 -> between
// 3 -> after
// I presume you mean all of these are date strings
const getStatus = (startTime, currentTime, endTime) => {
const dateStart = new Date(dateStr1); // Covert to a date
const dateTime = new Date(dateStr1);
const dateEnd = new Date(dateStr1);
const timestampStart = dateStart.getTime(); // Convert to a timestamp
const timestampTime = dateTime.getTime(); // Convert to a timestamp
const timestampEnd = dateEnd.getTime(); // Convert to a timestamp
if (timestampTime < timestampStart) {
return 'before'
}
if (timestampTime > timestampStart && timestampTime < timestampEnd) {
return 'between'
}
return "after"
}
For comparisons you might use the Date object:
// 6 am today
opens = new Date();
opens.setHours(6, 0, 0, 0); // setHours() accepts further arguments for minutes, seconds & milliseconds
// next midnight (00:00 tomorrow)
closes = new Date();
closes.setDate( closes.getDate() + 1 );
closes.setHours(0, 0, 0, 0);
current = new Date();
if(opens < current && current < closes) {
alert("This store is open right now.");
}
Regarding "If the end time is 23:59 (i.e. 11:59 PM ) this works, but if it is 00:00, my code fails.": If the end-time is lower than the start-time, you will have to add a day, since this time refers to somewhen tomorrow (even if it is the first second of the new day like in 00:00).

Difference between two dates. react-native (js)

I am trying to get the time that has happened between two dates.
Example:
oldDate = "4/16/2020, 12:00:00"
today = "5/17/2021, 1:00:50"
Result that a need:
years = 1
months = 1
days = 1
hours = 1
minutes = 0
seconds = 50
I also would like to refresh it every second, so that, the user can see it running.
Thanks.
Use Date.parse() to get a Date object from a string, subtract two dates using the - operator, and get the number of years, months, days, etc. using the corresponding methods. Then use setInterval to run it every second, and Date.now() to get the current time.
const oldDate = Date.parse("4/10/2020, 12:00:00");
// weird but seems to work with all dates
const getYear = (date) => date.getFullYear() - 1970;
const timeBetweenDates = (date1, date2) => {
const date = new Date(date1 - date2);
return {
years: getYear(date),
months: date.getMonth(),
days: date.getDay(),
hours: date.getHours(),
minutes: date.getMinutes(),
seconds: date.getSeconds(),
}
}
const pre = document.getElementById("display");
setInterval(() => {
pre.textContent = JSON.stringify(
timeBetweenDates(Date.now(), oldDate),
0,
2
);
}, 1000);
<pre id="display">Wait a second...</pre>

Check if the time difference is less than 1 second in moment

In my javascript project, I want to check if the time difference is less than 1 second. I use moment to get this difference. This is the function I have written to achieve it.
const withinOneSecond = (time) => {
const currentTime = moment();
return time + 1000 < currentTime;
};
But this doesn't work as expected. How can I check if the given time is within a second to the current time?
You can use moment#diff.
As an example, I've added a second to a date and taking the difference in with .diff passing seconds as second argument should return the difference in seconds
var a = moment();
var b = moment().add(1, 'seconds');
console.log(b.diff(a, 'seconds'))
<script src="https://momentjs.com/downloads/moment.js"></script>
The supported measurements are years, months, weeks, days, hours, minutes, and seconds. Here
For your particular case, you should be doing something like
const withinOneSecond = (time) => {
const currentTime = moment();
return currentTime.diff(time, 'seconds') == 1
};
var time = moment().add(1, 'seconds');
let results = withinOneSecond(time);
console.log(results);
<script src="https://momentjs.com/downloads/moment.js"></script>
You dont need moment for this. Use vanilla, use .getTime() to get time in milliseconds and compare it with the current time. See the code below:
var date = new Date();
const withinOneSecond = (time) => new Date().getTime() - new Date(time).getTime() < 1000;
setTimeout(() => {
console.log(withinOneSecond(date)); // true
}, 500)
setTimeout(() => {
console.log(withinOneSecond(date)); // false
}, 1500)
You just need to use the duration.asHours() method (see the docs).
const withinOneSecond = (time) => {
const currentTime = moment();
return moment.duration(currentTime.diff(time)).asSeconds() > 1;
};

Get time calculation from momentJS duration

I have a field in my table that I would like to sort. That field contains strings from MomentJS duration calculation. For example "20 Minutes", "10 Hours 1 Minute" and so on.
If I want to use a sort function I need to format that string back to lowest resolution of time I have which is minutes.
Like this: a: "20 Minutes" => 20.
b: "10 Hours 1 Minute" => 10*60 + 1 = 601.
So when sorting in a descending order b will come before a.
I made this function that does work but it is really hardcoded so I would really like to see other ways to solve it. Thanks!
function getTimeFromDuration(duration) {
const str = duration.split(' ');
const durationArray = ['Minute', 'Minutes', 'Hour', 'Hours', 'Day', 'Days'];
const calcArr = [];
let sum = 0;
for (let i=0; i<str.length; i++) {
const isNum = !isNaN(str[i]);
const isDuration = durationArray.includes(str[i]) > -1;
if (isNum) {
calcArr.push(parseInt(str[i]));
}
else if (isDuration) {
switch(str[i]) {
case 'Minute':
case 'Minutes':
calcArr.push(1);
break;
case 'Hour':
case 'Hours':
calcArr.push(60);
break;
case 'Day':
case 'Days':
calcArr.push(60*24);
break;
}
}
}
for (let j=0; j<calcArr.length; j=j+2) {
sum+= calcArr[j]*calcArr[j+1];
}
return sum;
}
console.log(getTimeFromDuration('1 Day 1 Hour 20 Minutes'));
I am not aware of a parsing function in Moment or elsewhere that will handle these types of strings. If your input strings are consistently formatted and limited to days, hours and minutes, then parsing them should not be all that difficult. Following is an approach along the lines of your original function, just a bit more compact due to some effort put into splitting the string into each duration "chunk" and then normalizing the duration descriptor (lowercase and singular) so you can easily access values from a multiplier object.
That said, if your original data contains the Moment duration object rather than just the string representation, then there are easier ways to do this.
const getMinutes = (s) => {
const multipliers = { day: 1440, hour: 60, minute: 1 };
const durations = s.split(/\s(?=\d)/);
let minutes = 0;
for (const d of durations) {
let [n, interval] = d.split(' ');
n = Number(n);
interval = interval.toLowerCase();
if (interval.endsWith('s')) {
interval = interval.slice(0, -1);
}
minutes += n * multipliers[interval];
}
return minutes;
};
const result = getMinutes('1 Day 1 Hour 20 Minutes');
console.log(result);
// 1520

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