SIGN IN SIGN UP

feat(scraps): Add RelativeTime component (#121854)

adds a `RelativeTime` card to `@sentry/scraps/relativeTime` — relative
time in the header, absolute time in the viewer's timezone and UTC.
Every `TimeSince` renders one, starting with the Last Seen and First
Seen columns on the issue feed.

**Before:**

<img width="255" height="177" alt="image"
src="https://github.com/user-attachments/assets/f98d705e-6961-4f20-8f34-f0538397a1ec"
/>

<img width="255" height="177" alt="image"
src="https://github.com/user-attachments/assets/f1c08b85-d9b3-436a-bc47-5a404f5a73b2"
/>

**After:**

Last seen 
<img width="255" height="177" alt="image"
src="https://github.com/user-attachments/assets/039801fe-d39c-4010-8ea3-885d81215f16"
/>


First seen
<img width="255" height="177" alt="image"
src="https://github.com/user-attachments/assets/7952adf7-dad0-40f4-80ef-9e5ac0c8b5e1"
/>

If only UTC is set (user didnt update their timezone in settings yet):

<img width="255" height="177" alt="image"
src="https://github.com/user-attachments/assets/70b00b36-83ad-4948-8712-cdffa6f5b05d"
/>

## Stack

Top of a 3 PR stack. This one needs both of the others:

1. #121983, the tooltip sections
2. #122063, the datetime provider
3. **this PR**, RelativeTime + TimeSince

## Review feedback addressed

- **Scraps no longer reaches into sentry for the timezone.**
`@sentry/scraps/datetime` owns the provider and sentry supplies the
value, in #122063. Same inversion as the tracking and link providers.
- **`TimeSince` always renders `RelativeTime`.** There's no way to get
one without the other now. `tooltipBody` remains for the callers that
replace the overlay wholesale.
- **Two rows, never three.** Viewer's timezone on top, UTC underneath.

## Open question

**Does `TimeSince` move into scraps in this PR, or the next one?**
Nothing blocks it: the only sentry import left in the file is `t` from
`sentry/locale`, which 35 components already in scraps import,
`RelativeTime` among them. So it's a file move plus rewriting 87
imports. That's ~90 mechanically changed files, which would bury the
part of this PR worth actually reading, so I'd rather be told which
you'd prefer to review.

## Known gap

The provider falls back to the browser's timezone when the viewer hasn't
configured one, but that branch can't be reached today. `UserSerializer`
resolves the option to `SENTRY_DEFAULT_TIME_ZONE` before it leaves the
API, so someone who never opened their settings is indistinguishable
from someone who chose UTC. Auto-detect needs the API to preserve that
state first, which is a backend PR.

No org timezone: neither the `Organization` type nor its serializer
carries one, and per Nate we'd rather not add a property to the org for
this.

story: `relativeTime.mdx`
<!-- [live
story](https://sentry-git-cv-scraps-relative-time.sentry.dev/stories/core/relativeTime)
-->

<!-- Closes DE-1513 -->
C
Chrisandra committed
857f1222770b93d1435cb32245c003a117849a61
Parent: 014c9df
Committed by GitHub <noreply@github.com> on 8/28/2026, 7:14:04 PM