1

I'm trying to calculate the age of the user in months, days, hours and minutes including leap years.. However, rather than using the select/option in HTML, I've input the options via Javascript. Due to this, I'm rather confused on how to do the calculations in Javascript now. Could anyone point me in the right direction to do these calculations?

HTML :

`  <ul class = "mainList">
    <h1>
      Age Calculator
    </h1>
    <h2> Enter Your Birthday</h2>
  <li class = "firstList">
    <p class = "datePara">
      Date:
    </p>
    <select id = "day">
    </select>
  </li>
  <li>
    <p class = "monthPara">
      Month:
    </p>
    <select id = "month">
    </select>
  </li>
  <li>
    <p class = "yearPara">
      Year:
    </p>
    <select id = "year">
    </select>
  </li>
  </ul>`

Javascript : `

var startyear = "1950";
var endyear = "2015";
var dat = new date();
var curday = dat.getDate();
var curmon = dat.getMonth() + 1;
var curyear = dat.getFullYear();


function initForm() {

  document.getElementById('day').focus();

for (var i = 1; i <= 31; i ++) {

  var thisDay = document.getElementById('day');
  var dayOption = document.createElement('option');

  dayOption.text = i;
  thisDay.add(dayOption, i);
}

for (var i = 1; i <= 12; i ++) {

  var thisMonth = document.getElementById('month');
  var monthOption = document.createElement('option');

  monthOption.text = i;
  thisMonth.add(monthOption, i);
}

for (var i = startyear; i <= endyear; i ++) {

  var thisYear = document.getElementById('year');
  var yearOption = document.createElement('option');

  yearOption.text = i;
  thisYear.add(yearOption, i);
}
}`
Seth Spivey
  • 347
  • 2
  • 4
  • 22
  • It is unclear what you are calculating. What does 1950 have to do with the person's age? – 001 Nov 19 '15 at 18:48
  • @JohnnyMopp The calculation should calculate their age from January 1st, 1950 or any other date they want to input between then and the current date. Sorry about the lack of clarity. – Seth Spivey Nov 19 '15 at 19:02
  • So, you are really just calculating the difference between 2 dates (today and some other date). It doesn't have anything to do with birthdays. For example, if you and I were both born after 1950, we would both have the same 1950-age, regardless of our birthdays. – 001 Nov 19 '15 at 19:06
  • @JohnnyMopp yeah, that description makes more sense than mine. – Seth Spivey Nov 19 '15 at 19:20
  • @SethSpivey: Can you provide sample input and expected output? For example, if someone was born 14 months ago to the day, would you say "1.2 years / 14 months / 420 days / ..." or would you say "1 year, 2 months, 0 days, ..."? – StriplingWarrior Nov 19 '15 at 20:09
  • @StriplingWarrior I'm inputting it via 3 separate selection tags. The output would be 'You have been living for: X years, X months and x days.' – Seth Spivey Nov 19 '15 at 22:58
  • @SethSpivey: First of all, that output doesn't match what you say in the first sentence of your post--which is correct? Secondly, I understood that you're taking input via controls on the page, but by "sample input and expected output" I mean, e.g. {input: {birthdate: "1/2/2003", today: "11/20/2015"} , output: "You have been living for 14 years, 10 months, and 18 days."} – StriplingWarrior Nov 20 '15 at 15:31

2 Answers2

0

MomentJS has a fromNow() function that will handle this automatically, taking care of leap years/local time/etc. It's pretty easy to use; you just instantiate a 'moment' from the time your user inputs and call moment.fromNow().

EDIT: Alternative with no moment:

day=document.getElementById('day').value;
month=document.getElementById('month').value;
year=document.getElementById('year').value;
birthdate=new Date(year, month-1, day); // 'month' is zero-indexed.
today = new Date();
age = (today-birthdate) / (1000*60*60*24*365.25);
// /1000 = seconds, /60=minutes, /60=hours, /24=days, /365.25=years, factor leap years

EDIT: I realize you're going to implement yourself, but here's a quick example anyway:

day=document.getElementById('day').value;
month=document.getElementById('month').value;
year=document.getElementById('year').value;
birthdate=new Date(year, month-1, day); // 'month' is zero-indexed.
today = new Date();
age = moment(today).diff(moment(birthdate), 'year');

You could skip the momentand just take the difference between the date objects (today-birthdate), which will give you the time interval in ms. The advantage of using the moment is that the time interval will be correct while factoring in leap years and the start date of the interval.

nrlakin
  • 5,234
  • 3
  • 16
  • 27
  • 1
    If you're going to suggest another tool, perhaps add in a bit of example code on how this would work for the poster? – Trasiva Nov 19 '15 at 17:42
  • @nrlakin I'd rather not use an outside tool. I'm trying to learn this rather than implement other sources to do it for me. Thank you for the suggestion though! – Seth Spivey Nov 19 '15 at 17:46
  • @SethSpivey That's fair, but note that this is definitely the kind of thing that's best suited to using library functions--it's a very common task that's easy to mess up! – nrlakin Nov 19 '15 at 19:33
  • @SethSpivey One thing you'll learn is that a lot of libraries are already built that will handle your end goals without having to reinvent the wheel. That's the beauty of the development community. – Trasiva Nov 19 '15 at 19:57
  • Both of your examples provide an age in *years*, whereas the OP asked for the age in Months, Days, Hours, and Minutes. – StriplingWarrior Nov 19 '15 at 20:06
0

To calculate something like this, you'll want to start by taking the difference between the years, months, days, etc., of the two dates:

var yearsBetween = currentDate.getYear() - targetDate.getYear();
var monthsBetween = currentDate.getMonth() - targetDate.getMonth();
var daysBetween = currentDate.getDate() - targetDate.getDate();
var hoursBetween = currentDate.getHours() - targetDate.getHours();
var minutesBetween = currentDate.getMinutes() - targetDate.getMinutes();
var secondsBetween = currentDate.getSeconds() - targetDate.getSeconds();

But some of these values will be negative. In those cases, you'll need to adjust the next-highest unit value to compensate:

if(secondsBetween < 0) {
  secondsBetween += 60;
  minutesBetween -= 1;
}
if(minutesBetween < 0) {
  minutesBetween += 60;
  hoursBetween -= 1;
}
...
if(daysBetween < 0) {
  // http://stackoverflow.com/a/1184359/120955
  var daysInTargetMonth = new Date(targetDate.getYear(), targetDate.getMonth() + 1, 0).getDate();
  daysBetween += daysInTargetMonth;
  monthsBetween -= 1;
}

Then, finally, it sounds like you don't care about years, so you'll want to roll those into the number of months:

monthsBetween += yearsBetween * 12;
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315