# Timestamp

## Usage

`Timestamp` renders one instant in a `<time>` element. `value` is an ISO string or a unix timestamp in seconds. The default format is `auto`: a relative phrase while the instant is inside `autoThreshold` (seven days), then `date_time`.

`hasTooltip` is on by default and opens a hover card that can be copied. Pass `tooltipEntries` to list the same instant in several zones or formats. `isTimezoneShown` appends a short zone name to `date_time` and `time`. `isLive` refreshes a relative reading on a short interval.

Relative text keeps a long zone name in `aria-label`, so the accessible name does not depend on the tooltip.

```vue
<script setup lang="ts">
import { Timestamp } from '@astryx-vue/core/Timestamp'
</script>

<template>
  <Timestamp value="2026-03-25T12:00:00Z" color="primary" />
</template>
```

### Anatomy

- **Formatted text**: The rendered date, time, or relative label like "2 hours ago" or "Mar 21, 2025".
- **Hover card**: A copyable hover card showing the full absolute date and time when the display is relative, or the rows configured via tooltipEntries. Its default single row carries the full absolute time.
- **Hover card row**: One row of the card: an optional label beside the instant rendered in one time zone and format. Rows opt into a copy button via isCopyable.
- **Copy button**: Per-row copy-to-clipboard button in the hover card; copies that row's formatted value.

## Best practices

| Guidance | Practices |
| --- | --- |
| Do | Use `auto` in feeds and comments. Recent events stay relative, older ones become a full date. |
| Do | Use `system_date`, `system_date_time`, and `system_time` in logs, with `type="code"`. |
| Do | Pass `tooltipEntries` when a reader must compare the local zone with the zone where an event happened. |
| Don't | Turn the tooltip off for a relative format unless something else nearby states the absolute time. |
| Don't | Append a zone to a system format. Those strings stay machine-readable. |

## Examples

### Timestamp — Auto

Auto format that shows relative time for recent dates and switches to the full date for older ones. The default choice for most use cases.

```vue
<script setup lang="ts">
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
import { Timestamp } from '@astryx-vue/core/Timestamp'

const now = Date.now() / 1000
</script>

<template>
  <Stack direction="vertical" :gap="4">
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'Recent — renders as relative' }}
      </Text>
      <Stack align="center" direction="horizontal" :gap="4" wrap="wrap">
        <Timestamp :value="now - 300" format="auto" color="primary" />
        <Timestamp :value="now - 7200" format="auto" color="primary" />
        <Timestamp :value="now - 86400" format="auto" color="primary" />
      </Stack>
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'Older than 7 days — renders as date_time' }}
      </Text>
      <Stack align="center" direction="horizontal" :gap="4" wrap="wrap">
        <Timestamp value="2025-01-15T09:30:00Z" format="auto" color="primary" />
        <Timestamp value="2024-06-01T14:00:00Z" format="auto" color="primary" />
      </Stack>
    </Stack>
  </Stack>
</template>
```

### Timestamp — Colors

Timestamp rendered in each available color variant: primary, secondary, disabled, and accent.

```vue
<script setup lang="ts">
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
import { Timestamp } from '@astryx-vue/core/Timestamp'

const DATE = '2026-02-19T17:00:00Z'
</script>

<template>
  <Stack direction="vertical" :gap="4">
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        Primary
      </Text>
      <Timestamp :value="DATE" format="date_time" color="primary" />
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        Secondary
      </Text>
      <Timestamp :value="DATE" format="date_time" color="secondary" />
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        Disabled
      </Text>
      <Timestamp :value="DATE" format="date_time" color="disabled" />
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        Accent
      </Text>
      <Timestamp :value="DATE" format="date_time" color="accent" />
    </Stack>
  </Stack>
</template>
```

### Timestamp — Formats

All display formats side by side: date, date_time, time, and their system equivalents. Use date and date_time for user-facing UI, system variants for logs and dev tools.

```vue
<script setup lang="ts">
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
import { Timestamp } from '@astryx-vue/core/Timestamp'

const DATE = '2026-02-19T17:00:00Z'
</script>

<template>
  <Stack direction="vertical" :gap="4">
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'User-facing formats' }}
      </Text>
      <Stack align="center" direction="horizontal" :gap="4" wrap="wrap">
        <Timestamp :value="DATE" format="date" color="primary" />
        <Timestamp :value="DATE" format="date_long" color="primary" />
        <Timestamp :value="DATE" format="date_weekday" color="primary" />
        <Timestamp :value="DATE" format="date_time" color="primary" />
        <Timestamp :value="DATE" format="time" color="primary" />
      </Stack>
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'System formats (logs and dev tools)' }}
      </Text>
      <Stack align="center" direction="horizontal" :gap="4" wrap="wrap">
        <Timestamp :value="DATE" format="system_date" type="code" color="primary" />
        <Timestamp :value="DATE" format="system_date_time" type="code" color="primary" />
        <Timestamp :value="DATE" format="system_time" type="code" color="primary" />
      </Stack>
    </Stack>
  </Stack>
</template>
```

### Timestamp — Relative

Relative time labels from seconds to months ago, with hover tooltips showing the full date. Use in feeds, comment threads, and activity logs.

```vue
<script setup lang="ts">
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
import { Timestamp } from '@astryx-vue/core/Timestamp'

const now = Date.now() / 1000
</script>

<template>
  <Stack direction="vertical" :gap="3">
    <Text type="supporting" color="secondary">
      {{ 'Relative timestamps (hover for full date)' }}
    </Text>
    <Stack direction="vertical" :gap="2">
      <Timestamp :value="now - 5" format="relative" color="primary" />
      <Timestamp :value="now - 120" format="relative" color="primary" />
      <Timestamp :value="now - 3600" format="relative" color="primary" />
      <Timestamp :value="now - 86400" format="relative" color="primary" />
      <Timestamp :value="now - 259200" format="relative" color="primary" />
      <Timestamp :value="now - 90 * 86400" format="relative" color="primary" />
    </Stack>
  </Stack>
</template>
```

### Timestamp — Timezone

Timestamps with the timezone abbreviation appended. Enable isTimezoneShown for audiences across time zones, like audit logs or team calendars.

```vue
<script setup lang="ts">
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
import { Timestamp } from '@astryx-vue/core/Timestamp'

const DATE = '2026-02-19T17:00:00Z'
</script>

<template>
  <Stack direction="vertical" :gap="4">
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'User-facing with timezone' }}
      </Text>
      <Stack align="center" direction="horizontal" :gap="4" wrap="wrap">
        <Timestamp :value="DATE" format="date_time" is-timezone-shown color="primary" />
        <Timestamp :value="DATE" format="time" is-timezone-shown color="primary" />
      </Stack>
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'System formats stay machine-readable — never suffixed with a zone' }}
      </Text>
      <Stack align="center" direction="horizontal" :gap="4" wrap="wrap">
        <Timestamp :value="DATE" format="system_date_time" type="code" color="primary" />
        <Timestamp :value="DATE" format="system_time" type="code" color="primary" />
      </Stack>
    </Stack>
  </Stack>
</template>
```

### Timestamp — Tooltip time zones

Hover tooltips that show one instant across several time zones or formats. Use tooltipEntries when readers must compare zones.

```vue
<script setup lang="ts">
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
import { Timestamp } from '@astryx-vue/core/Timestamp'

const DATE = '2026-02-19T17:00:00Z'
</script>

<template>
  <Stack direction="vertical" :gap="4">
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'Local + UTC — hover to compare' }}
      </Text>
      <Timestamp
        :value="DATE"
        format="relative"
        color="primary"
        :tooltip-entries="[
          { format: 'date_time', label: 'Local' },
          { timezoneID: 'UTC', format: 'date_time', label: 'UTC' },
        ]"
      />
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'Incident origin zone alongside the reader’s' }}
      </Text>
      <Timestamp
        :value="DATE"
        format="date_time"
        color="primary"
        :tooltip-entries="[
          { format: 'date_time', label: 'Local' },
          { timezoneID: 'America/Los_Angeles', format: 'date_time', label: 'Origin' },
        ]"
      />
    </Stack>
    <Stack direction="vertical" :gap="1">
      <Text type="supporting" color="secondary">
        {{ 'Friendly line plus a machine-precise line' }}
      </Text>
      <Timestamp
        :value="DATE"
        format="date_time"
        color="primary"
        :tooltip-entries="[
          { format: 'full' },
          { format: 'system_date_time', label: 'ISO' },
        ]"
      />
    </Stack>
  </Stack>
</template>
```

## Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | `string \| number` | - | An ISO instant, or unix seconds. Written to the `datetime` attribute. |
| `format` | `TimestampFormat` | `'auto'` | `relative`, `relative_short`, `auto`, `date`, `date_long`, `date_weekday`, `date_time`, `time`, `system_date`, `system_date_time`, `system_time`, or `unix_seconds`. |
| `autoThreshold` | `number` | `604800` | Seconds before `auto` switches from a relative phrase to `date_time`. |
| `hasTooltip` | `boolean` | `true` | Shows a hover card with a copyable absolute time. `tooltipEntries` replaces the default lines. |
| `tooltipEntries` | `TimestampTooltipEntry[]` | - | Each entry picks a format, an optional `timezoneID`, and an optional label. |
| `isTimezoneShown` | `boolean` | `false` | Appends a short zone name to `date_time` and `time`. |
| `isLive` | `boolean` | `false` | Refreshes a relative reading. The interval lengthens as the instant gets older. |
| `type` | `TextType` | `'supporting'` | Typography role passed to `Text`. |
| `size` | `TextSize` | - | Optional size override. |
| `color` | `TextColor \| 'disabled'` | `'secondary'` | `disabled` is painted by this component. The other names are text colors. |
| `weight` | `TextWeight` | - | Optional weight override. |

An unknown <code>timezoneID</code> warns in the console and falls back to the local zone.

## Theming

The visible text uses the text tokens for the chosen color. <code>disabled</code> uses <code>--astryx-color-text-disabled</code>. The hover card is the shared <code>HoverCard</code>.
