Reputation: 489
I'm looking for a way to use momentjs to parse two dates, to show the difference.
I want to have it on the format: "X years, Y months, Z days".
For the years and months the moment library and modulo operator works nice. But for the days it's another tale as I don't want to handle leap years and all that by myself. So far the logic I have in my head is this:
var a = moment([2015, 11, 29]);
var b = moment([2007, 06, 27]);
var years = a.diff(b, 'years');
var months = a.diff(b, 'months') % 12;
var days = a.diff(b, 'days');
// Abit stuck here as leap years, and difference in number of days in months.
// And a.diff(b, 'days') returns total number of days.
return years + '' + months + '' + days;
Upvotes: 41
Views: 41037
Reputation: 41
All the solutions presented here are failing for some of the test cases. So I made some changes to the accepted answer.
function getYMD(date1, date2) {
const a = moment(date1);
const b = moment(date2);
var years = a.diff(b, 'year');
b.add(years, 'years');
const noOfDaysInb = b.daysInMonth();
const noOfDaysIna = a.daysInMonth();
let months = 0;
if (noOfDaysInb > noOfDaysIna) {
months = b.diff(a, "months");
a.add(months, "months");
} else {
months = a.diff(b, 'months');
b.add(months, 'months');
}
var days = a.diff(b, 'days');
return {
years: Math.abs(years),
months: Math.abs(months),
days: Math.abs(days),
}
}
This is the best answer I can come up with.
Upvotes: 1
Reputation: 1549
I just converted @Josh Crozier's answer into a function and added hours, minutes and seconds too.
function diffYMDHMS(date1, date2) {
let years = date1.diff(date2, 'year');
date2.add(years, 'years');
let months = date1.diff(date2, 'months');
date2.add(months, 'months');
let days = date1.diff(date2, 'days');
date2.add(days, 'days');
let hours = date1.diff(date2, 'hours');
date2.add(hours, 'hours');
let minutes = date1.diff(date2, 'minutes');
date2.add(minutes, 'minutes');
let seconds = date1.diff(date2, 'seconds');
console.log(years + ' years ' + months + ' months ' + days + ' days ' + hours + '
hours ' + minutes + ' minutes ' + seconds + ' seconds');
return { years, months, days, hours, minutes, seconds};
}
Upvotes: 3
Reputation: 5502
Use this
var totalDays = endDate.diff(startDate, "days");
Upvotes: -1
Reputation: 6887
This is another answer. Verified with Age Calculator
function calculateAge(){
ageText = jQuery("#dob").closest(".form-group").find(".age-text");
ageText.text("");
level2.dob = jQuery("#dob").val();
if(!level2.dob) return;
level2.mdob= moment(level2.dob, 'DD-MM-YYYY');
if(!level2.mdob.isValid()){
alert("Invalid date format");
return;
}
level2.targetDate = moment();//TODO: Fill in the target date
level2.months = level2.targetDate.diff(level2.mdob, 'months'); // Calculate the months
let years = parseInt(level2.months/12); // A year has 12 months irrespective or leap year or not
let balanceMonths = level2.months%12; // The balance gives the number of months
let days;
if(!balanceMonths){ // If no balance months, then the date selected lies in the same month
months = 0; // so months = 0
days = level2.targetDate.diff(level2.mdob, 'days'); // only the days difference
}else{
months = balanceMonths;
dob_date = level2.mdob.date();
target_month = level2.targetDate.month();
construct_date = moment().month(target_month).date(dob_date);
days = level2.targetDate.diff(construct_date, 'days')+1; // There might be one day missed out. Not sure on UTC
}
ageText = years +" years " + months+ " months " + days +" days";
}
Upvotes: -1
Reputation: 277
Above solution is not working with momentjs 2.19.1
Then with reference of Date of Joining calculation not working with moment 2.19.1 I have implemented new solution with latest solution for momentjs 2.19.1.
Required npm packages:
"moment": "^2.19.4",
"moment-duration-format": "^1.3.0",
"react-moment": "^0.6.8",
import following in reactjs:
import moment from "moment";
import Moment from "react-moment";
import momentDurationFormatSetup from "moment-duration-format";
var DOJ = moment([work_data.joining_date]).format("YYYY,MM,DD");
var today = moment().format("YYYY,MM,DD");
var totalMonths = parseInt(moment(today).diff(moment(DOJ), 'months'));
var totalDuration = moment.duration(totalMonths, "months").format();
if(totalDuration.search('1y') > -1) {
totalDuration = totalDuration.replace("1y", "1 Year,");
} else {
totalDuration = totalDuration.replace("y", " Years,");
}
if(totalDuration.search('1m') > -1){
totalDuration = totalDuration.replace("1m", "1 Month");
} else {
totalDuration = totalDuration.replace("m", " Months");
}
console.log(totalDuration);
Upvotes: 2
Reputation: 3353
Moment.js also has duration
object. A moment is defined as single point in time, whereas duration is defined as a length of time which is basically what you want.
var a = moment([2015, 11, 29]);
var b = moment([2007, 06, 27]);
var diffDuration = moment.duration(a.diff(b));
console.log(diffDuration.years()); // 8 years
console.log(diffDuration.months()); // 5 months
console.log(diffDuration.days()); // 2 days
What @Josh suggest may work, but is definitely not the right way of calculating difference in 2 moments.
Upvotes: 41
Reputation: 240938
You could get the difference in years and add that to the initial date; then get the difference in months and add that to the initial date again.
In doing so, you can now easily get the difference in days and avoid using the modulo operator as well.
var a = moment([2015, 11, 29]);
var b = moment([2007, 06, 27]);
var years = a.diff(b, 'year');
b.add(years, 'years');
var months = a.diff(b, 'months');
b.add(months, 'months');
var days = a.diff(b, 'days');
console.log(years + ' years ' + months + ' months ' + days + ' days');
// 8 years 5 months 2 days
I'm not aware of a better, built-in way to achieve this, but this method seems to work well.
Upvotes: 81