Ad
  • Custom User Avatar

    It's not exactly that, we don't "add" days to a date, we create a new date with the original month and day, but with an incremented year. It's just that when you create a date with a day out of the bounds of the month (like January, 32nd or February, 29th on non-leap years, or even day = -1) the function changes the month so that the date will stay valid (so Date("January, 32nd") === Date("February, 1st"))

    That's important because if we "just" added one year everytime, a date starting on February, 29th would stay stuck on March, 1st forever (didn't I say April earlier? Maybe I should go learn the month of the year xD)

    Not sure if that was clear enough, to make it simpler we don't add a set number of days because that would depend on leap years, which is quite a pain in the ass (a year is a leap year if it's divisible by 4, but not by 100 except when it's also divisible by 400 (in which cas it's still a leap year)... And it's not added in the algorithm but we should add a leap year when divisible by 1000).

    Well, we don't care about that: when given for instance 2012, 2, 29, we just create a new date with incremented year (2013, 2, 29) and all the boring leap year check is made by the Date object. And we check if we're still on February and if the weekday is the same. While not we keep incrementing (2014, 2, 29, 2015, 2, 29, 2016, 2, 29, ...)

  • Custom User Avatar

    No, your assumption is perfectly right that we need both t1.getDay() == t0.getDay and t1.getMonth() == t0.getMonth() to stop the loop (because of 29 February + 1 year giving a 1st April).

    Thus, we need to LOOP while t1.getDay() != t0.getDay OR t1.getMonth() != t0.getMonth(), which is equivalent to !(t1.getDay() == t0.getDay && t1.getMonth() == t0.getMonth()) (we keep looping while the current year is not a perfect birthday)

    A (maybe clearer) equivalent would be

    while (true) {
        t1.setFullYear(t0.getFullYear() + ++i, t0.getMonth(), t0.getDate());
        return i if (t1.getDay() == t0.getDay() && t1.getMonth() == t0.getMonth())
    }
    

    But I prefer avoiding return statements in a loop whenever possible.