Closed Bug 1873590 Opened 1 year ago Closed 1 year ago

date summary of "last yr" not very useful

Categories

(Core :: Internationalization, defect)

defect

Tracking

()

RESOLVED FIXED
125 Branch
Tracking Status
firefox125 --- fixed

People

(Reporter: jrmuizel, Assigned: nordzilla)

Details

Attachments

(1 file)

I have a bunch of tabs that get a most recently used date summary of "last yr." This gives impression of tab not being used for over year which likely isn't true. For example, I had a tab open for https://www.youtube.com/watch?v=kaaATngW8iY which is a video from Oct 23 2023. YouTube summarizes that as "2 months ago" vs. Firefox View's "last yr.". Oct 23 was 2 months and 16 days ago and so "2mo ago" feels like a more useful description.

FWIW, YouTube goes up to "11 months ago" and then switches to "1 year ago" which feels like a more intuitive way for things to work.

The severity field is not set for this bug.
:jsudiaman, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(jsudiaman)

This has to do with how MozRelativeTimeFormat formats periods of time, it's not specific to Fx View.

Component: Firefox View → Internationalization
Flags: needinfo?(jsudiaman)
Product: Firefox → Core

The severity field is not set for this bug.
:m_kato, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(m_kato)

threshold.year is 2 now.

Severity: -- → S3
Flags: needinfo?(m_kato)

Does that mean it's fixed now?

Flags: needinfo?(m_kato)

(In reply to Jeff Muizelaar [:jrmuizel] from comment #5)

Does that mean it's fixed now?

No. default is 2. (https://searchfox.org/mozilla-central/rev/9e5b13e92b50c61e60a42bdc2cb2e5966ae28795/toolkit/components/mozintl/mozIntl.sys.mjs#146).

Erik, do you know why this threshold is 2 for year.

Flags: needinfo?(m_kato) → needinfo?(enordin)

Exploration

This code definitely seems to be intentional. I've created some experimental test cases here that show consistent behavior:

    anchor = new Date("2016-08-28 12:00");
    testRTFBestUnit(anchor, "2016-05-27 23:59", "3 months ago");
    testRTFBestUnit(anchor, "2016-04-27 23:59", "4 months ago");
    testRTFBestUnit(anchor, "2016-03-27 23:59", "5 months ago");
    testRTFBestUnit(anchor, "2016-02-27 23:59", "6 months ago");
    testRTFBestUnit(anchor, "2016-01-27 23:59", "7 months ago");
    testRTFBestUnit(anchor, "2015-12-27 23:59", "last year");

    anchor = new Date("2016-01-28 12:00");
    testRTFBestUnit(anchor, "2015-12-27 23:59", "last month");
    testRTFBestUnit(anchor, "2015-11-27 23:59", "2 months ago");
    testRTFBestUnit(anchor, "2015-10-27 23:59", "last year");

This threshold of 2 months seems to revert to last year only when it does, indeed, cross a year boundary.

I did some more digging to see if there is a specification for this, but I did not find anything. Instead, I found this in the Firefox Source Docs:

"This API is in the process of standardization and in its raw form will not handle any calculations to select the best unit. It is intended to just offer a way to format a value. mozIntl wrapper extends the functionality providing the calculations and allowing the user to get the current best textual representation of the delta."

So I believe that this threshold is both arbitrary and unique to Mozilla.

I also agree that saying "last year" for something only two months ago feels awkward, and I would be in favor of increasing the threshold.


Next steps

I think this warrants a discussion of what the new value should be, if we update the value. This affects what the code calls "year-distant" formatting, in which case the boundary extends beyond the calendar year into the past or the future. Ultimately this is the threshold at which the formatting becomes a "catch-all" value for dates that are to be perceived as "distant," beyond the year boundary.

The current implementation is 2 months, e.g.

  • It's February and we are looking at something 3 months ago, it will say "last year"
  • It's November and we're looking at something 3 months from now, it will say "next year"

My personal opinion is that 2 feels too short, but something like 11 feels like it too long. I don't have an intuitive sense of exactly what month was 11, 10, or 9 months ago, for example. I'd have to stop and think for a moment.

I think that I would be in favor of 6, but I think 4 or 8 are reasonable choices as well.


Jeff, Makoto, thoughts?

Flags: needinfo?(m_kato)
Flags: needinfo?(jmuizelaar)
Flags: needinfo?(enordin)

I think 12 makes the most sense. That seems to be what https://date-fns.org/v2.29.3/docs/intlFormatDistance does and avoids having to know what 11, 10, or 9 months ago is.

Flags: needinfo?(jmuizelaar)

I do think you're right that 12 is the intended value.

I had a chat with Zibi as well (the original patch author), and he confirmed that his source was likely this, which uses 12.

I think the value of 2 is a typo, and was intended to be 12 from the start.


I'll go ahead and take this and put up a patch with tests.

Assignee: nobody → enordin
Flags: needinfo?(m_kato)
Attachment #9380485 - Attachment description: WIP: Bug 1873590 - Fix MozRelativeTimeFormat month threshold r=#platform-i18n-reviewers! → Bug 1873590 - Fix MozRelativeTimeFormat month threshold r=#platform-i18n-reviewers!
Pushed by enordin@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/69009edbf485 Fix MozRelativeTimeFormat month threshold r=platform-i18n-reviewers,gregtatum

Why did you end up choosing 11 months instead of 12?

Flags: needinfo?(enordin)

Hey Jeff,

After looking into it more, I agree that the logical limit should be 12 months.

The way that the existing threshold code seems to be implemented, setting the threshold N - 1 made the most sense to me. See also, for example, the way that the threshold values for minute and second are 59 instead of 60.

const threshold = {
  ...
  minute: 59, // at least 59 minutes before using hour.
  second: 59, // at least 59 seconds before using minute.
};

I think that the test cases I added are reasonable and demonstrate the behavior:

    let anchor = new Date("2016-04-10 12:00:00");
    testRTFBestUnit(anchor, "2015-04-01 00:00", "last year");
    testRTFBestUnit(anchor, "2015-05-01 00:00", "11 months ago");
    testRTFBestUnit(anchor, "2015-12-01 00:00", "4 months ago");
    testRTFBestUnit(anchor, "2016-02-01 00:00", "2 months ago");
    let = new Date("2016-12-29 18:30");
    testRTFBestUnit(anchor, "2017-02-12 18:30", "in 2 months");
    testRTFBestUnit(anchor, "2017-07-12 18:30", "in 7 months");
    testRTFBestUnit(anchor, "2017-11-29 18:30", "in 11 months");
    testRTFBestUnit(anchor, "2017-12-01 18:30", "next year");

This is what seemed correct to me, but if you think this is wrong, I'd be happy to re-evaluate. There is plenty of time before soft freeze.

Flags: needinfo?(enordin) → needinfo?(jmuizelaar)

What does:

    let anchor = new Date("2016-04-10 12:00:00");
    testRTFBestUnit(anchor, "2015-04-15 00:00"...);

give?

Flags: needinfo?(jmuizelaar)

(In reply to Jeff Muizelaar [:jrmuizel] from comment #15)

What does:

    let anchor = new Date("2016-04-10 12:00:00");
    testRTFBestUnit(anchor, "2015-04-15 00:00"...);

give?

The above code would yield "last year" for being in the same month of the previous calendar year.

This makes sense to me, based on how I understand the algorithm.

I didn't write the algorithm, but my understanding is that, for the time range we are considering, the granularity is counted in months until it hits the threshold to start counting in years.


With Threshold = 11

With the current threshold set to 11, the exact boundaries would work like this:

    // Currently middle of April
    anchor = new Date("2016-04-15 12:30:30");

    // April of the previous calendar year
    testRTFBestUnit(anchor, "2015-04-01 00:00:00", "last year");
    testRTFBestUnit(anchor, "2015-04-30 23:59:59", "last year");

    // May of the previous calendar year
    testRTFBestUnit(anchor, "2015-05-01 00:00:00", "11 months ago");
    testRTFBestUnit(anchor, "2015-05-31 23:59:59", "11 months ago");

    // June of the previous calendar year
    testRTFBestUnit(anchor, "2015-06-01 00:00:00", "10 months ago");

    // April of the next calendar year
    testRTFBestUnit(anchor, "2017-04-30 23:59:59", "next year");
    testRTFBestUnit(anchor, "2017-04-01 00:00:00", "next year");

    // March of the next calendar year
    testRTFBestUnit(anchor, "2017-03-31 23:59:59", "in 11 months");
    testRTFBestUnit(anchor, "2017-03-01 00:00:00", "in 11 months");

    // February of the next calendar year
    testRTFBestUnit(anchor, "2017-02-28 23:59:59", "in 10 months");

With Threshold = 12

If I were to set the threshold to 12, it would work like this:


    // Currently middle of April
    anchor = new Date("2016-04-15 12:30:30");

    // March of the previous calendar year
    testRTFBestUnit(anchor, "2015-03-01 00:00:00", "last year");
    testRTFBestUnit(anchor, "2015-03-31 23:59:59", "last year");

    // April of the previous calendar year
    testRTFBestUnit(anchor, "2015-04-01 00:00:00", "12 months ago");
    testRTFBestUnit(anchor, "2015-04-30 23:59:59", "12 months ago");

    // May of the previous calendar year
    testRTFBestUnit(anchor, "2015-05-01 00:00:00", "11 months ago");

    // May of the next calendar year
    testRTFBestUnit(anchor, "2017-05-31 23:59:59", "next year");
    testRTFBestUnit(anchor, "2017-05-01 00:00:00", "next year");

    // April of the next calendar year
    testRTFBestUnit(anchor, "2017-04-30 23:59:59", "in 12 months");
    testRTFBestUnit(anchor, "2017-04-01 00:00:00", "in 12 months");

    // March of the next calendar year
    testRTFBestUnit(anchor, "2017-03-31 23:59:59", "in 11 months");

Outlook

I would find it strange to go up fully to 12 months, refraining from counting in years until the 13th month.
The same way that I think it would be strange to go fully up to "60 minutes ago" and not start counting in hours until the 61st minute.

In that way, it makes sense to me that the threshold for minutes is 59, and the threshold for months is now 11.

But I'm certainly open to further consideration here. This is our own internal code and there doesn't appear to be an officially approved spec or standard (yet).

Do you find 12 to be more reasonable?

Flags: needinfo?(jmuizelaar)
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 125 Branch

I don't think 12 is more reasonable and I don't think there are perfect answers to what to do here. Let's leave it for now, and we can always adjust it in the future as needed.

Flags: needinfo?(jmuizelaar)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: