1

I have a date of birth for each user in my application. E.g. the format is 29/01/2015

My code at the moment calculates the years from today's date and the provided date of birth:

((new Date((new Date().getTime() - new Date(user.dob).getTime())).getFullYear()) - 1970)

For the example above this will retrieve the number 3 since it has been three years since 29/01/2015.

What would be a good optimization for getting the months if the year is below 1?

For example for this date: 21/03/2018, my code will return 0 since a full year has not passed yet. How could I optimize my logic to retrieve 6 months which is the time between today(21/09/2018) and 21/03/2018?

P.S. I would like to avoid the use of any libraries.

EDJ
  • 843
  • 3
  • 17
  • 37
  • there's no real reason NOT to use a library like a momentjs. In fact, I'd even argument it's better to use one. It's tried and tested, it definitely works. Most probably you will be adding some more date manipulation and formatting, which means that if you're going with vanilla js you'll be adding more and more functionality that has already been figured out and dealt with. And which is hard to replace later on. – Creynders Sep 21 '18 at 16:00
  • You're not parsing the date correctly, and using the Date constructor to calculate the difference in years is a poor approximation. There are plenty of existing answers on how to do both. – RobG Sep 21 '18 at 21:14

3 Answers3

3

I would use momentjs is a cool library for the datetime related stuff. Anyway my approach would be - calculates the months - then check months more than 12 then i grab years from the months - unless show the months

With moment: Live sample with moment

let months = moment('2011-06-11').diff(moment('2011-04-11'), 'month', true);

if (months >= 12) {
    console.log('years:', (months - (months %12))/12 );
} else {
    console.log('only months', parseInt(months));
}

With pure js: Live sample with pure JS

let dateFrom = new Date('2011-04-11');
let dateTo = new Date('2011-06-11');

let months = dateTo.getMonth() - dateFrom.getMonth() + (12 * (dateTo.getFullYear() - dateFrom.getFullYear()));

if (months >= 12) {
    console.log('years:', (months - (months %12))/12 );
} else {
    console.log('only months', parseInt(months));
}
Ntwobike
  • 2,406
  • 1
  • 21
  • 27
  • While this will certainly do the job for me, do you think it is possible to accomplish this without MomentJS? I would really prefer not to add a new library to my project just for a small thing like this. – EDJ Sep 21 '18 at 13:35
  • i added with and without moment @IamOptimus – Ntwobike Sep 21 '18 at 13:46
1

I recently used the below code for one of my project and it works. Note, i am also using momentjs which is free and opensource to download and use.

Here is the sample jsfiddle link http://jsfiddle.net/n70vdz1k/

var dob = "13-05-1981";
mdob = moment(dob, 'DD-MM-YYYY'); // date of birth
if (!mdob.isValid()) {
    alert("Invalid date format");
    return;
}
targetDate = moment(); //this will give today's date
months = targetDate.diff(mdob, 'months');
let years = parseInt(months / 12);
let balanceMonths = months % 12;
let days;
if (!balanceMonths) {
    months = 0;
   // days = targetDate.diff(mdob, 'days');
    dob_date = mdob.date();
    target_month = targetDate.month();
    construct_date = moment().month(target_month).date(dob_date);
    days = targetDate.diff(construct_date, 'days');
    if(days < 0){
        days = 30 + days;
    }
} else {
    months = balanceMonths;
    dob_date = mdob.date();
    target_month = targetDate.month();
    construct_date = moment().month(target_month).date(dob_date);
    days = targetDate.diff(construct_date, 'days');
     if(days < 0){

        days = 30 + days;
    }
}

console.log("months", months)
console.log("years", years)
console.log("days", days)
Alaksandar Jesus Gene
  • 6,523
  • 12
  • 52
  • 83
1

You could simply compute the difference yourself:

function diffYears(d) {
  return Math.floor((Date.now() - new Date(d)) / 12 / 30 / 24 / 3600 / 1000);
}

function diffMonths(d) {
  return Math.floor((Date.now() - new Date(d)) / 30 / 24 / 3600 / 1000);
}

console.log(diffMonths('2018-03-21'), diffYears('2018-03-21'));
console.log(diffMonths('2017-03-21'), diffYears('2017-03-21'));
console.log(diffMonths('2016-03-21'), diffYears('2016-03-21'));
Martin Adámek
  • 16,771
  • 5
  • 45
  • 64