Problem/Motivation

Function format_interval() in the file: includes/common.inc returns in some cases wrong value "1" instead of correct value of given interval.

For example:
1 min 1 sek instead of 31 min 21 sec.

The $units variable is array with keyed singular|plural.

$units = array(
    '1 year|@count years' => 31536000,
    '1 month|@count months' => 2592000,
    '1 week|@count weeks' => 604800,
    '1 day|@count days' => 86400,
    '1 hour|@count hours' => 3600,
    '1 min|@count min' => 60,
    '1 sec|@count sec' => 1
  );

These keys are used as parameters in function format_plural(). This function calls locale_get_plural() function, if exists. Function locale_get_plural() returns plural form index for a specific number. The index is computed from the formula of given language. In short, it returns 0 if number is singular.

Some languages (f.e. Czech - langcode "cs") use singulars for numbers ending with number 1 (f.e. 21, 31.. 91, 101 etc.). That's why locale_get_plural() returns 0 = singular.

Czech language plural formula snippet ($language->formula):

if ((((n % 10) == 1) && ((n % 100) != 11))) {
    $plural = ((0));
}

The problem is that all singulars in format_interval() are hardcoded to 1, so function returns 1 instead of 21. This function is used in Views for "Time ago" formater, so all views with time ago formater for Czech language display wrong values.

Step to reproduce

  • Locale module must be enabled.
  • Add Czech language at admin/config/regional/language

Use this simple test:

$time_diffs = array(21, 31, 41, 51, 81);
  foreach ($time_diffs as $time_diff) {
    $timeago1 = format_interval($time_diff, 2, 'cs');
    $timeago2 = format_interval($time_diff, 2, 'en');
    print $time_diff . ' sec. = ' . $timeago1 . ', should be ' . $timeago2;
    print '<br>';
  }

Results:

21 sec. = 1 sek, should be 21 sec
31 sec. = 1 sek, should be 31 sec
41 sec. = 1 sek, should be 41 sec
51 sec. = 1 sek, should be 51 sec
81 sec. = 1 min 1 sek, should be 1 min 21 sec

Proposed resolution

The $units key for singular could contain @count instead of "1".

$units = array(
    '@count year|@count years' => 31536000,
    '@count month|@count months' => 2592000,
    '@count week|@count weeks' => 604800,
    '@count day|@count days' => 86400,
    '@count hour|@count hours' => 3600,
    '@count min|@count min' => 60,
    '@count sec|@count sec' => 1
  );

Tested for test code above and works well.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

martin_klima created an issue. See original summary.

martin_klima’s picture

martin_klima’s picture

Status: Active » Needs review
martin_klima’s picture

Issue summary: View changes
radimklaska’s picture

Good catch Martin!

Steps I took to reproduce this:

  • install D7 in Czech language using profiles/standard/translations/drupal-7.43.cs.po (Installing in English and enabling Czech language afterwards will probably require manual localization of date formats)
  • drush en views views_ui devel devel_generate
  • create new view (gist with view export: https://gist.github.com/anonymous/843204b2540599573d16b0d273f61e9d )
    • sort by post date
    • Add Content: Post date formatted as Time ago (with "ago" appended)
  • Generate e.g. 50 articles, created in last hour
  • Check the view

Martin's patch fixes the issue and applies cleanly.

radimklaska’s picture

Version: 7.43 » 8.2.x-dev
Component: base system » language system
Status: Needs review » Needs work
Issue tags: +localization, +Needs backport to D7

D8 has the same problem. If I'm not mistaken it needs to be fixed in D8 first and then backported. So, updating...

radimklaska’s picture

Status: Needs work » Needs review
FileSize
3.49 KB

Same fix, updated for D8.

Status: Needs review » Needs work

The last submitted patch, 7: counts_for_singulars_in-2712603-7.patch, failed testing.

radimklaska’s picture

Hmm, tests failing... I thought that @count will just be replaced by "1" and the result will be the same. We will have to take a look at the test and figure out why it's failing...

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

The last submitted patch, 7: counts_for_singulars_in-2712603-7.patch, failed testing.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Chi’s picture

Status: Needs work » Needs review
FileSize
15.14 KB

Patch for Drupal 10.

Chi’s picture

Version: 11.x-dev » 10.1.x-dev
andypost’s picture

smustgrave’s picture

Status: Needs review » Needs work

#25 failed

Chi’s picture

Status: Needs work » Needs review
FileSize
15.02 KB
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative, +Bug Smash Initiative

Thanks for fixing that.

Seems like a valid cleanup. The existing test updates seem adequate.

quietone’s picture

Version: 10.1.x-dev » 11.x-dev
FileSize
571 bytes
15.03 KB

I'm triaging RTBC issues. I re-read the IS and the comments. I didn't find any unanswered questions.

The array was originally added in #76802: Introduce placeholder magic into t(). The first patch in that issue has the array with the hardcoded '1 sec' and I didn't see any discussion in that issue about changing that.

I skimmed the patch and saw this. I am able to fix that now.

+++ b/core/lib/Drupal/Core/Datetime/DateFormatter.php
@@ -291,7 +291,7 @@ public function formatDiff($from, $to, $options = []) {
+        // to avoid skipping levels and getting output like "@count year @count second".

Comment should be wrapped at 80 columns.

This should also be on 11.x

catch’s picture

Title: Counts for singulars in format_interval() are hardcoded to 1 » Counts for singulars in DateFormatter::formatInterval() are hardcoded to 1

  • catch committed e0116bc9 on 11.x
    Issue #2712603 by Chi, quietone, martin_klima, radimklaska: Counts for...
catch’s picture

Committed/pushed to 11.x, thanks! This introduces a new translated string so tagging for 10.2.0 strings changes.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.