Skip to content

fix(i18n): formatRelativeTime renders every future date as "Just now" while its doc promises "in 3 days" #263

Description

@koniz-dev

Context

LocalizedFormatters.formatRelativeTime
(lib/core/localization/localized_formatters.dart:168-189) documents itself
as producing both past and future phrasings:

Format relative time (e.g., "2 hours ago", "in 3 days")

The implementation cannot produce a future phrasing at all. It computes
now.difference(dateTime), which is negative for any future date, so
every > 0 branch is skipped and the fall-through returns
l10n.minutesAgo(difference.inMinutes.clamp(0, 59)) - and minutesAgo(0)
renders as "just now" in every shipped locale.

Verified with a probe test (temporary file, since removed):

$ flutter test test/_audit_probe_test.dart
in 3 days -> "Just now"
in 2 hours -> "Just now"
00:00 +1: All tests passed!

(probe body: LocalizedFormatters.formatRelativeTime(DateTime.now().add(const Duration(days: 3)), locale: const Locale('en')))

An adopter formatting a deadline, a scheduled event, or a task due date -
the natural uses of relative time in exactly the kind of app this template
scaffolds - silently gets "Just now" for everything upcoming. The existing
tests (test/core/localization/localized_formatters_test.dart:194-260)
only cover past dates, so nothing guards this.

Two acceptable resolutions; the criteria below allow either, but the
decision must be explicit:

  • (a) implement future phrasings ("in X days" etc.) with properly extracted
    plural strings in all four ARB files, or
  • (b) declare the API past-only: fix the doc comment, and give future input
    a defined, tested behavior (e.g. clamp to "just now" documented as
    such
    ).

Acceptance criteria

  1. The doc comment on formatRelativeTime matches what the function
    actually returns for a future DateTime. Observable: the example strings
    in the doc are ones a flutter test case reproduces.
  2. flutter test test/core/localization/localized_formatters_test.dart
    passes with new cases passing DateTime.now().add(...) for at least
    Duration(hours: 2) and Duration(days: 3), asserting the chosen
    behavior - localized future phrasing under (a), or the documented
    defined output under (b).
  3. Under (a) only: the future strings come from the ARB files (all four
    locales), not from string interpolation in Dart, and a test asserts a
    non-English locale renders a non-English future phrasing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    epic:i18nlib/l10n, lib/core/localization, l10n.yaml: ARB catalogs and locale plumbingpriority:P3Nice to have: cosmetic, speculative, or long tailtype:bugSomething that is broken relative to documented behavior

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions