Fix month and year diffs #571
One downfall of this method is that the same issue of having slightly different percentages still exists between months with different lengths, so July 15 to August 15 != 1 month.
This also includes diffs between February and February when one is on a leap year and one is not. Feb 1 2012 to Feb 1 2013 != 1.
Nice hack :) I just want to lay down my thoughts on this, I have to try and implement them to see if it is worth it.
We can use the same logic for years (keep full years + days/[days in this/previous year]). It requires a check to see if the date of month/year is before the start day/date -- in the 5th Jan to 4th Feb case, we check that 4 < 5, so we count the month before Feb's days, if >= 5, then we count Febs days.
I'm not sure that trading one set of issues (the ones we have now) with the ones created by the current solution is worth while. I'm also not sure if the more complicated solution outlined above is worth implementing to fix some minor glitches like the ones we face now.
EDIT: Argh! My solution won't work well on diffs near the end of the month, like 31Jan to 28Feb would be 28/31 of a month, and 31Jan to 1Mar would be 1 month + 30/28 :)
Hmm, I like your idea, what about something like this instead.
I think the most common use case for year diffs is birthday calculation and age gating, thus I think we should optimize for comparing two moments with the same day of the month.
So Jan 15 to Feb 15 should be exactly 1 month. Feb 28 to Mar 28 should be exactly 1 month. Feb 28 2011 to Feb 28 2012 should be exactly 1 year.
There are two numbers used to calculate months/years. The integer difference and the partial difference.
The integer difference would stay the same as in the pull request.
The partial difference is changed to the following.
We do not use % through month
We calculate the difference between the number of days through month
// Jan 1 - Jan 3 1 - 3 = -2; // difference in days (31 + 31) / 2 = 31; // average month length -2 / 31 = -0.0654; // the partial difference in months 0 - 0 = 0; // the integer difference in months 0 + -0.0654 = -0.0654; // the total difference in months
// Jan 15 - Feb 15 15 - 15 = 0; // difference in days (31 + 28) / 2 = 29.5; // average month length 0 / 29.5 = 0; // the partial difference in months 0 - 1 = -1; // the integer difference in months -1 + 0 = -1; // the total difference in months
// Jan 31 - Feb 28 31 - 28 = 3; // difference in days (31 + 28) / 2 = 29.5; // average month length 3 / 29.5 = 0.101; // the partial difference in months 0 - 1 = -1; // the integer difference in months -1 + 0.101 = -0.899; // the total difference in months
// Jan 31 - Mar 1 31 - 1 = 30; // difference in days (31 + 31) / 2 = 31; // average month length 30 / 31 = 0.9677; // the partial difference in months 0 - 2 = -2; // the integer difference in months -2 + 0.9677 = -1.0323; // the total difference in months
It does get a little weird toward the ends of two months with different lengths, but I think there is always going to be some weirdness in assigning a numerical value to something like this.
Yes, your proposal does work for full months, and it does provide some results in the other cases. I thought about this some more and I come to the conclusion that there are so many contradictory edge cases in the way humans work with time that we'd better not try to work "humanly" for all of them.
So this last proposal has the least surprise, I'm for it.
the average doesn't really solve the problem, these results are wrong:
// -0.423728813559322 moment('2013-01-23').diff('2013-02-06', 'month', true) // -0.03531073446327684 moment('2013-01-23').diff('2013-02-06', 'year', true)
The "fractional year" gets trickier when the
For an implementation reference see mout/mout#82
it's not working for me i'm getting start date and end date from api and it's returning 0