Calculations of years and months wrong due to leap years
See original GitHub issueThe constants used for milliseconds in a year and milliseconds in a month are incorrect because they are computed from the slightly naïve understanding of leap days in the Gregorian calendar.
A leap day occurs every four years. However, because that’s actually slightly too often, if the year is divisible by 100 then it is not a leap year. However, because that would be too infrequent, if the year is divisible by 400 they it is a leap year.
Thus the correct decimal representation of the average length of a year is 365.2425
days. Likewise, since the year is 12 exact months, an average length of a month is 30.436875
days.
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (4 by maintainers)
Top Results From Across the Web
Excel incorrectly assumes that the year 1900 is a leap year
NOTE: Microsoft Excel correctly handles all other leap years, including century years that are not leap years (for example, 2100). Only the ......
Read more >Calendar Calculations - NASA
So to correct (approximately), we add 1 day every four years (leap year). Thus, three calendar years are 365 days long; the fourth...
Read more >Leap year problem - Wikipedia
The leap year problem is a problem for both digital (computer-related) and non-digital ... results from errors in the calculation of which years...
Read more >The leap year and the law | Legal Blog
Every four years is a leap year, a year with an additional day in the month of February. How does this additional day...
Read more >The math behind leap years.
So after four years the calendar is behind by a day. The Earth has spun one extra time over those four years, and...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Did some more thinking about this, finally.
I think there are a few distinct questions at hand:
The answer to the first question is easy: if we change anything, then it’s a breaking change. (I started a branch for the next major version if you want to follow along.)
The other two questions are trickier.
Wikipedia provides a list of time units. Milliseconds, seconds, minutes, hours, days, and weeks are constant. Months and years, however, have a range. In other words, it’s easy to answer “how long is an hour, in milliseconds?” and impossible to answer “how long is a month, in milliseconds?”
To inform what we should do, I looked at what other folks do.
timedelta
only goes up to weeks, presumably because of this ambiguity.Duration
stringification only goes up to hours, and they claim “days can be different lengths”. I don’t know more about this.distance_of_time_in_words
sidesteps this problem with inexact measurements (e.g., “about 6 years”).pretty-ms
says that years are 365 days and doesn’t support months or weeks, after the maintainer acknowledged this ambiguity.Many others don’t deal with this problem at all:
dateutils.relativedelta
doesn’t seem to do humanization at all, and durations for units don’t seem to be specified..diff
function is date-aware, but HumanizeDuration.js only deals with milliseconds (even so, they had a bunch of issues with month/year differences)My rough takeaway from the above: if your library deals with exact durations (e.g., “1.7 minutes” instead of “about 2 minutes”), then you either (1) don’t deal with months and years (2) treat them carefully.
I’d like to continue to support months and years, because I think they’re useful.
Given that, I think HumanizeDuration.js should:
mo
andy
from the default list. For example, by default, humanizing 400 days should humanize to57 weeks, 1 day
, not something like1 year, 1 month, ...
.mo
andy
, and allow them to set the unit duration as they see fit. This is already supported with theunitMeasures
option.mo
andy
, as is done in #157.If that sounds good, I’ll do this in the next major version.
Ah dates, always more complicated than I think.
I think your change in #157 is worthy but suffers from a similar problem as the issue reported in #152—these are arguably breaking changes. And because this library is in maintenance mode, I’m hesitant. However, they are also arguably bug fixes, in which case they would be in scope.
What do you think?