Cards show 0 years ago for videos that are eleven months old. Reported on a
video published 20 August 2025 and read on 18 August 2026 — Yo
8B30
uTube says
11 months about the same video.
formatTimeAgo in ui/src/i18n/index.tsx measures months and years with two
different approximations:
const mo = Math.floor(d / 30);
const y = Math.floor(d / 365);
const [value, unit]: [number, Intl.RelativeTimeFormatUnit] =
...
: d < 30 ? [d, "day"]
: mo < 12 ? [mo, "month"]
: [y, "year"];
Between them there is a gap of five days:
363 days mo = ⌊363/30⌋ = 12 → too many to still say months
y = ⌊363/365⌋ = 0 → not enough to say one year
The month branch is left at twelve and the year branch is entered at nought, so
the card says 0 years ago. It is not one video: every video crosses days 360
to 364 of its life, once a year, for as long as it is in a library. A feed of a
few hundred videos has one in it most weeks.
Suggested behaviour
Count calendar months rather than thirty-day blocks, and derive years from
them, so the two units cannot disagree:
const months = (to.getFullYear() - from.getFullYear()) * 12 + (to.getMonth() - from.getMonth())
- (to.getDate() < from.getDate() ? 1 : 0);
const years = Math.floor(months / 12);
That also makes a year arrive on the day it comes round rather than five days
late, and it agrees with what YouTube shows for the same video.
Below a month nothing needs to change — a day is a day whichever month it falls
in, and only months and years have edges that move.
One edge worth deciding rather than discovering: thirty days that land inside a
single calendar month, 15 January to 14 February, are no complete month at all.
The day branch has already been left by then, and 0 months ago is no better
than 0 years ago, so it wants a floor of one.
Happy to open a PR; it is formatTimeAgo and a handful of tests.
Cards show
0 years agofor videos that are eleven months old. Reported on avideo published 20 August 2025 and read on 18 August 2026 — Yo 8B30 uTube says
11 monthsabout the same video.formatTimeAgoinui/src/i18n/index.tsxmeasures months and years with twodifferent approximations:
Between them there is a gap of five days:
The month branch is left at twelve and the year branch is entered at nought, so
the card says
0 years ago. It is not one video: every video crosses days 360to 364 of its life, once a year, for as long as it is in a library. A feed of a
few hundred videos has one in it most weeks.
Suggested behaviour
Count calendar months rather than thirty-day blocks, and derive years from
them, so the two units cannot disagree:
That also makes a year arrive on the day it comes round rather than five days
late, and it agrees with what YouTube shows for the same video.
Below a month nothing needs to change — a day is a day whichever month it falls
in, and only months and years have edges that move.
One edge worth deciding rather than discovering: thirty days that land inside a
single calendar month, 15 January to 14 February, are no complete month at all.
The day branch has already been left by then, and
0 months agois no betterthan
0 years ago, so it wants a floor of one.Happy to open a PR; it is
formatTimeAgoand a handful of tests.