github / relative-time-element

Web component extensions to the standard <time> element.
https://github.github.io/relative-time-element/examples/
MIT License
3.57k stars 170 forks source link

Feb 29th showing as 'yesterday' on March 31 #281

Closed Esbylion closed 5 months ago

Esbylion commented 7 months ago

Minimal reproduction:

<html>
<body>
<relative-time datetime="2024-02-29 07:20:54.629275+00:00"></relative-time>
<script type="module" src="https://unpkg.com/@github/relative-time-element@latest/dist/bundle.js"></script>
</body>
</html>

Screenshot from 2024-03-31 at 6:03 PM, GMT +11 Screenshot from 2024-03-31 18-03-43

This appears the same on Firefox for Android, Firefox on Linux Mint, Firefox on Windows 10, and Edge on Windows 10.

depoulo commented 7 months ago

Might be related: https://twitter.com/depoulo/status/1620703935186231302

sixmachine-6 commented 5 months ago

May be the library or the component handling the relative-time is not updating it correctly instead we can a create a custom script to handle the time Am i correct mam/sir?

silverwind commented 5 months ago

Bug is reproducible on GitHub today:

image

currently it's 2024-05-31T12:16:54.112Z

2024-05-01T12:32:52.000Z renders "30 days ago" which is ok 2024-05-01T05:33:40.000Z renders "now" but should be "31 days ago" or "a month ago" 2024-04-30T12:39:36.000Z renders "yesterday" but should be "32 days ago" or "a month ago"

It only happens when the current date is near the end of a month. It looks like all subsequent dates after the point where it breaks are off by 1 month.

lilyinstarlight commented 5 months ago

It happens because of JavaScript date math and the reliance on difference between .getMonth() calls after .setMonth() calls for relative time rounding, in this case when duration.days === 0 and duration.months === -1 and relativeTo === new Date('2024-05-31')

[I] lily@bina ~> node
Welcome to Node.js v22.2.0.
Type ".help" for more information.
> let date = new Date()
undefined
> date
2024-05-31T18:32:29.029Z
> date.getMonth()
4
> date.setMonth(3)
1714588349029
> date.getMonth()
4
> date
2024-05-01T18:32:29.029Z
>

I've got a patch cooked up to fix this anomaly by correcting "May 31 minus 1 month" to be equal to "April 30" rather than "May 1". I don't know if that is semantically what is desired by this library, but I've never touched or used this library before really so I don't know very well what would be "expected" outputs

lilyinstarlight commented 5 months ago

I've opened #285 to fix this behavior

GBirkel commented 5 months ago

This is all over github right now. April 30th in my repo renders as "yesterday".

If I'm reading this correctly, this is happening because "less than one month ago" is being considered the equivalent of "this month". That shortcut equivalence is obviously flawed. Tweaking the definition of "one month ago" is not the solution. Making a better calculation for "this month" is.

I assume "this month" should be based on converting "now" into a timestamp with the same time zone as the given timestamp, and then asking for only the month value and comparing the two, yes?

daz10000 commented 5 months ago

I think the true fix is to standardize the month to be 28 days consistently but in the interim this needs some serious test coverage. It's May 31st and April 30th is yesterday..

image

GBirkel commented 5 months ago

That would work. We could call the extra 13th month "Decemburary", and the one leftover day in the year could be called "bonus day", during which absolutely nothing works, so it's a worldwide holiday. We could even tweak the length of "bonus day" to fix the whole leap-year problem!

daz10000 commented 5 months ago

Month 13th could be nulluary or "Month Does Not Exist". Last day of year we take the day off to celebrate vanquishing all timedate bugs.

depoulo commented 5 months ago

If it worked for the Eastman Kodak Company, it could work for GitHub 🤷🏽