1

I am just writing a program to calculate the passage of time from the day of birth and the time left until my next birthday (JavaScript). I do not know how to take into account the time zones and leap years, which is why errors in calculations come to me - days and hours do not match.

var year; //variable that stores the user's birthday year
var month; //variable that stores the user's birthday month
var day; //variable that stores the user's birthday day

var todayDate = new Date();//variable that stores today's date

var currentYear = todayDate.getFullYear();//variable that stores current year
var currentmonth = todayDate.getMonth();//variable that stores current month
var currentday = todayDate.getDay();//variable that store current day 
var birthday = new Date(year, month, day);// generate date of birthday
var differentdate = (todayDate.getTime() - birthday.getTime()) /1000;//diffrence in time between the date of birth and the current one
//var y = 31622400;//the number of seconds in a leap year
const x = 31557600;//the number of seconds in a year

var passyear = Math.floor(differentdate / x);//variable that stores the years that have passed
var passday = Math.floor((differentdate % x) / 86400);//variable that stores the days that have passed
var numhours = Math.floor(((differentdate % x) % 86400) / 3600);//variable that stores the hours that have passed
var numminutes = Math.floor((((differentdate % x) % 86400) % 3600) / 60);//variable that stores the minutes that have passed
var numseconds = Math.floor((((differentdate % x) % 86400) % 3600) % 60);//variable that stores the seconds that have passed
//The condition checking the next birthday;
if (currentmonth > month) {
var futureDate = new Date((currentYear + 1), month, day);

} else if (currentmonth === month) {
   if (currentday >= day) {
   futureDate = new Date((currentYear + 1), month, day);
   } else {
   futureDate = new Date(currentYear, month, day);
            }

} else {
  futureDate = new Date(currentYear, month, day);
         }
         ;

var nextbirth = (futureDate - todayDate) / 1000;
var nextday = Math.floor((nextbirth % x) / 86400);
var nexthours = Math.floor(((nextbirth % x) % 86400) / 3600);
var nextminutes = Math.floor((((nextbirth % x) % 86400) % 3600) / 60);
var nextseconds = Math.floor((((nextbirth % x) % 86400) % 3600) % 60);
  • You should consider using https://momentjs.com/ It may be worth reading through the documentation to see how they handle the issues you mention but I'd just use the library since they've solved the problems for you. – JasonB Jan 29 '18 at 03:44
  • @JasonB—before recommending a library you should first check if it suits. Moment.js does not have a built-in function that returns differences in years, months, etc., it only returns one unit. – RobG Jan 29 '18 at 07:07
  • Probably a duplicate of [*How to get the difference of two dates in mm-dd-hh format in Javascript*](https://stackoverflow.com/questions/35504942/how-to-get-the-difference-of-two-dates-in-mm-dd-hh-format-in-javascript) or [*Difference between two dates in years, months, days in JavaScript*](https://stackoverflow.com/questions/17732897/difference-between-two-dates-in-years-months-days-in-javascript). Note that months and years have differing lengths, and days may have differing lengths if the host observes daylight saving, you can't use constants to represent their lengths. – RobG Jan 29 '18 at 07:11
  • Library != one method with a magic answer function. Using moment.js, read the docs and use the library, will result in a handful of lines of readable code that handles ops concerns regarding leap years and time zones. – JasonB Jan 29 '18 at 07:24
  • @JasonB—I disagree regarding "handful of lines of readable code", see the answer to [*Moment.js Get difference between two dates in the dd:hh:mm:ss format?*](https://stackoverflow.com/questions/28657113/moment-js-get-difference-between-two-dates-in-the-ddhhmmss-format#) which only deals with h:mm:ss, it doesn't address years, months and days (I've posted a comparison answer in POJS in less code). If you think the OP's question can be done in just a few lines of moment.js code, post an answer. ;-) – RobG Jan 29 '18 at 09:27

1 Answers1

0

Here is an implementation using the Moment.js library. It is more than just a handful of lines :) but I find this code more readable even though the difference function still feels a bit clunky.

var month = "01"; // january
var day = "15"; // 15
var year = "1975";

var birthdate = moment(month + ' ' + day + ' ' + year, "MM DD YYYY");
var now = moment();
var nextBirthday = moment(month + ' ' + day + ' ' + now.year(), "MM DD YYYY");
if (nextBirthday < now) {
  nextBirthday.add(1, 'year');
}

console.log('birth date: ' + birthdate.format('MM/DD/YYYY'));
console.log('now: ' + now.format('MM/DD/YYYY'));
displayTimeDifference(now, birthdate);

console.log('next birthday: ' + nextBirthday.format('MM/DD/YYYY'));
console.log('now: ' + now.format('MM/DD/YYYY'));
displayTimeDifference(nextBirthday, now);

function displayTimeDifference(firstDate, secondDate) {
  let d1 = firstDate.clone(),
    d2 = secondDate.clone(),
    years = d1.diff(secondDate, 'years'),
    months = d1.subtract(years, 'years').diff(d2, 'months'),
    days = d1.subtract(months, 'months').diff(d2, 'days'),
    hours = d1.subtract(days, 'days').diff(d2, 'hours'),
    minutes = d1.subtract(hours, 'hours').diff(d2, 'minutes'),
    seconds = d1.subtract(minutes, 'minutes').diff(d2, 'seconds');

  console.log('years:' + years + ' months:' + months + ' days:' + days + ' hours:' + hours + ' minutes:' + minutes + ' seconds:' + seconds);
}
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>
JasonB
  • 6,243
  • 2
  • 17
  • 27