-2

I need to calculate the exact difference between two dates in days, months and years.

I have this function:

const getAge = (dateString) => {
    const today = new Date();
    const birthDate = new Date(dateString);
    let age = today.getFullYear() - birthDate.getFullYear();
    const m = today.getMonth() - birthDate.getMonth();
    if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
        age -= 1;
    }
    return age;
};

It receives a date in YYYY-MM-DD format. At this time it outputs a exact number of years (6 years, or 5 if it's before "birthday").

I need it to output 5 years, 11 months and 29 days (as an example).

How can I achieve that?

angelod1as
  • 95
  • 1
  • 11
  • 2
    In general I'd suggest using [Moment.js](https://momentjs.com/) if possible if you are doing any large amount of work on dates. It would let you get the [difference](https://momentjs.com/docs/#/displaying/difference/) and format that duration any way you want. – Karl Reid May 09 '17 at 16:50
  • 2
    This question gets asked all the time. Try to search before you ask. – Domino May 09 '17 at 16:55

2 Answers2

2

Maybe this can help you

const getAge = (dateString) => {
    const today = new Date();
    const birthDate = new Date(dateString.replace(/-/g, '/'));
    const yearsLater = new Date((birthDate.getFullYear()+1)+"/"+(birthDate.getMonth()+1)+"/"+birthDate.getDate());
    const monthsLater = new Date((birthDate.getFullYear())+"/"+(birthDate.getMonth()+2)+"/"+birthDate.getDate());
    const daysLater = new Date((birthDate.getFullYear())+"/"+(birthDate.getMonth()+1)+"/"+(birthDate.getDate()+1));

    years = Math.floor((today-birthDate)/(yearsLater-birthDate));
    dateMonths  = (today-birthDate)%(yearsLater-birthDate);
    months = Math.floor(dateMonths / (monthsLater-birthDate));
    dateDays = dateMonths % (monthsLater-birthDate);
    days = Math.floor(dateDays / (daysLater-birthDate));
    return {"years": years, "months": months, "days": days};
};
willicab
  • 64
  • 5
  • You should post your code as a runnable snippet. Note that the OP's string format is YYYY-MM-DD which will be parsed as UTC. Your code builds and parses strings in the format YYYY/M/D which may not be parsed correctly at all, but likely as local, so introducing an error equal to the host timezone offset. Why build a string and rely on unreliable parsing when you can give the values directly to the Date constructor? – RobG May 09 '17 at 22:57
  • Using today's date gives `{years: -1, months: -1, days: -1}`, and '2016-05-11' on 2017-05-10 gives `{years: 0, months: 11, days: 47}`. – RobG May 09 '17 at 23:16
  • My bad, i have edited the code with a replace, now works with 'YYYY/MM/DD' and 'YYYY-MM-DD' – willicab May 10 '17 at 14:14
  • But it should not use `new Date((birthDate.getFullYear()+1)+"/"+(birthDate.getMonth()+1)+"/"+birthDate.getDate());`. Adding a year to a date may create an invalid date (2016/02/29 -> 2017/02/09), also some browsers will treat 2016/02/29 as an invalid version of 2016-02-29. There is no need to create then parse a string, pass values directly to the Date constructor: `new Date((birthDate.getFullYear()+1), birthDate.getMonth(), birthDate.getDate())` which avoids all parsing issues (because there is no parsing). ;-) – RobG May 10 '17 at 22:54
1

The best solution for me is to use mementjs https://momentjs.com library.

After that try this :

var d1= Date.parse("2017/05/08");
var d2= Date.parse("2015/07/15");

var m = moment(d1);
var years = m.diff(d2, 'years');
m.add(-years, 'years');
var months = m.diff(d2, 'months');
m.add(-months, 'months');
var days = m.diff(d2, 'days');

var result = {years: years, months: months, days: days};
console.log(result);