I have had an issue on several things now with date not accounting for leap year.

Calendars have been off, age is incorrect etc.

Most recently I have used Views timeago selector and date of birth field. For every 4-7 years of age the age is off by 1 day cumulatively.
Example.
Age 5 is off by 1 day
Age 9 is off by 2 days
Age 13 is off by 3 days etc.

At first I thought it was Views but tracing it back, it looks like it is the DATE module. I am not a programmer, but it looks like it may be differences in date & dateTime or perhaps dateInterval. I would love to be able to fix it myself but I am afraid I would break more than I fix.

Does anyone have a solution for this issue?

TIA

Issue fork date-2875478

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

garymullins created an issue. See original summary.

garymullins’s picture

Is no one else having a problem with this?
Is there a fix I am missing?
I have searched and have not found a solution. If one exist, can you point me in the right directions?
Thanks in advance

lodey’s picture

I also am having this issue. Looking around I also found this post - looks like the date module is not allowing for leap years. I have no solution yet, but may just find another way to display this info for my use case.

Andrew Dolgov’s picture

Version: 7.x-2.10 » 7.x-2.x-dev
Component: Code » Date API
Status: Active » Needs review
FileSize
4.12 KB

core format_interval function works wrong, re-implemented with date alternative function, that use date->diff() and two calendar points, not interval in seconds

Status: Needs review » Needs work
DamienMcKenna’s picture

I appreciate you taking the time to work on a patch for this. However, the PHP 5.3 tests fail, so at the very least it can't be committed as-is.

Ronino’s picture

Status: Needs work » Needs review
FileSize
5.55 KB

I reworked patch #4:

  1. made it apply to the latest version
  2. reworked theme_date_time_ago()
    1. use REQUEST_TIME as current timestamp like date_format_interval() does
    2. fixed the logic of the "raw time span" and "inverse time span" display types
  3. reworked format_date_interval()
    1. added "weeks" as unit like format_interval() has
    2. added documentation
    3. renamed it to _date_format_interval() and moved it to date_api.module
  4. also adapted date_format_interval() which was the last function to use format_interval()

I can't really provide an interdiff as #4 fails to apply.

This not only affects leap years, but intervals in general. Like @Andrew correctly stated, the reason is core's format_interval() which only knows about the interval in seconds, but not about the dates. So with the fix, for example the difference between Jan 1st and Feb 1st as well as Feb 1st and Mar 1st is both "1 month" while format_interval() would return "1 month 1 day" and "4 weeks" (i.e. 28 days) respectively.

Ronino’s picture

I improved #7 to only compare actual dates if the given date doesn't have a time set. So the difference between now and tomorrow is "1 day" and not e.g. "8 hours" if it's 4 p.m.

DamienMcKenna’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

This is great, thank you.

I think we really need to have test coverage, just to make sure the logic works as expected and ensure we don't run into regressions later on.

Ronino’s picture

Status: Needs work » Needs review
FileSize
9.52 KB
4.37 KB

This patch adds tests.

Some tests can fail though and I'm not sure how to handle this (see DateApiTestCase::testDateInterval()): Any interval that contains fractions of a day (e.g. 1 hour) will fail if the current time is that interval before midnight (e.g. 23:00:00). This is due to the constructor of DateObject considering any date with a time of 00:00:00 as "dateOnly", resulting in a "1 day" interval instead of "1 hour" as the times are ignored.

I tested them at different times using the timecop PHP extension (https://github.com/kiddivouchers/php-timecop):

timecop_freeze(strtotime('2022-01-31 23:00:00'));

The tests revealed that it makes a difference (pun intended) for DateTime::diff() in what order the dates are used. I fixed this in _date_format_interval().

DamienMcKenna’s picture

That's great work, Ronino!

Here's the tests on their own to hopefully confirm the problem, i.e. this should fail.

Status: Needs review » Needs work

The last submitted patch, 11: date-n2875478-10-tests-only.patch, failed testing. View results

kunal_sahu made their first commit to this issue’s fork.

kunal_sahu’s picture

Please review this patch . Hope this passes the test.

Thanks

kunal_sahu’s picture

Status: Needs work » Needs review
kunal_sahu’s picture

Please ignore #14 Patch.

Status: Needs review » Needs work

The last submitted patch, 14: 2875478-14.patch, failed testing. View results