# 时间戳

## 使用方法

`Timestamp` 用 `<time>` 画出一个时刻。`value` 是 ISO 字符串，或按秒计的 unix 时间。默认格式是 `auto`：在 `autoThreshold`（七天）以内用相对时间，更早的用 `date_time`。

`hasTooltip` 默认打开，悬停卡片里的时间可以复制。`tooltipEntries` 把同一个时刻列成几种时区或格式。`isTimezoneShown` 在 `date_time` 和 `time` 后面加上短时区名。`isLive` 按较短的间隔刷新相对时间。

相对格式会把带长时区名的说法放进 `aria-label`，不依赖提示卡片也能读出绝对时间。

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

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

## 建议

| 建议 | 做法 |
| --- | --- |
| 推荐 | 动态和评论用 `auto`。近的显示相对时间，远的变成完整日期。 |
| 推荐 | 日志用 `system_date`、`system_date_time`、`system_time`，并配 `type="code"`。 |
| 推荐 | 读者需要对照本地时区和事件发生时区时，传入 `tooltipEntries`。 |
| 避免 | 相对格式关掉提示，除非旁边已经写了绝对时间。 |
| 避免 | 给系统格式再追加时区。那些字符串要保持机器可读。 |

### 结构

- **格式化文字**: 渲染出的日期、时间或相对标签，比如「2 小时前」或「2025年3月21日」。
- **悬停卡片**: 显示为相对时间时，这张可复制的悬停卡片给出完整的绝对日期和时间；也可以用 tooltipEntries 配置各行。默认的单行带着完整的绝对时间。
- **悬停卡片行**: 卡片的一行：可选标签，旁边是按一个时区和一种格式渲染的时刻。一行要不要复制按钮，由 isCopyable 决定。
- **复制按钮**: 悬停卡片里每一行的复制按钮，复制的是该行格式化后的值。

## 示例

### Timestamp — 自动

较近的时间显示成相对时间，更早的切换成完整日期。大多数场景用这个默认值。

```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 — 颜色

主色、次要色、禁用色和强调色。

```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 — 格式

日期、日期时间、时间，以及对应的系统格式。面向读者用前者，日志和开发工具用系统格式。

```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 — 相对时间

从几秒前到几个月前。悬停可以看到完整日期，适合动态、评论和活动记录。

```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 — 时区

在时间后面加上时区缩写。跨时区的审计日志或团队日历打开 isTimezoneShown。

```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 — 提示中的时区

悬停提示把同一个时刻列成几种时区或格式，方便对照读者所在时区和事件发生时区。

```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>
```

## 属性

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `value` | `string \| number` | - | ISO 时刻，或按秒计的 unix 时间。会写到 `datetime`。 |
| `format` | `TimestampFormat` | `'auto'` | `relative`、`relative_short`、`auto`、`date`、`date_long`、`date_weekday`、`date_time`、`time`、`system_date`、`system_date_time`、`system_time` 或 `unix_seconds`。 |
| `autoThreshold` | `number` | `604800` | `auto` 从相对时间换成 `date_time` 的秒数门槛。 |
| `hasTooltip` | `boolean` | `true` | 悬停卡片里是可复制的绝对时间。`tooltipEntries` 会替换默认行。 |
| `tooltipEntries` | `TimestampTooltipEntry[]` | - | 每一项选择一种格式、可选的 `timezoneID` 和可选标签。 |
| `isTimezoneShown` | `boolean` | `false` | 在 `date_time` 和 `time` 后面加上短时区名。 |
| `isLive` | `boolean` | `false` | 刷新相对时间。间隔会随时刻变远而变长。 |
| `type` | `TextType` | `'supporting'` | 传给 `Text` 的排版角色。 |
| `size` | `TextSize` | - | 可选的字号覆盖。 |
| `color` | `TextColor \| 'disabled'` | `'secondary'` | `disabled` 由本组件自己上色。其余名称是文字颜色。 |
| `weight` | `TextWeight` | - | 可选的字重覆盖。 |

不认识的 <code>timezoneID</code> 会在控制台警告，并回退到本地时区。

## 主题

可见文字使用所选颜色对应的文字 token。<code>disabled</code> 使用 <code>--astryx-color-text-disabled</code>。悬停卡片是共用的 <code>HoverCard</code>。
