> For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/llms-full.txt.

# Chrono 概览

Chrono 决定调度器如何表示时间、计算经过的天数，以及确定下次到期时间。模型使用以天为单位的间隔，Chrono 负责把这些间隔与应用中的时间值连接起来。

## 选择预设

从 `ts-fsrs` 导入 `dateChrono`、`numericChrono`、`temporalInstantChrono` 和 `defineChrono`。

| 预设                      | 时间值                | 天数运算                                                                                             |
| ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------ |
| `dateChrono`            | JavaScript `Date`  | `difference` 默认计算 UTC 日期差；`fractionalDays: true` 时按固定 24 小时计算经过的小数天数。`add` 始终按固定 24 小时增加天数，支持小数。 |
| `numericChrono`         | 以天为单位的数字           | `difference(from, to)` 为 `to - from`；`add(from, days)` 为 `from + days`。                          |
| `temporalInstantChrono` | `Temporal.Instant` | 支持配置时区，并可选择是否保留时间差的小数天数。                                                                         |

各预设的详细说明： [Date](https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/guide/chrono/date.md)、[Numeric](https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/guide/chrono/numeric.md)、[Temporal Instant](https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/guide/chrono/temporal-instant.md)。

## 定义与运行时操作

`Chrono` 定义包含 `schema`、`normalize`、`defaultValue` 和 `create`。将定义传给 `defineScheduler({ model, chrono })`；需要单独进行时间运算时，调用定义的 `create({ config })`。调度器也通过 `scheduler.chrono` 暴露配置完成的运行时对象。

Date 和 Temporal 需要向 `create({ config })` 传入完整配置；只有 Numeric 等不需要配置的预设可以无参调用 `create()`。通过调度器创建实例时，会校验配置并补齐 schema 默认值。

| 操作                     | 含义                                            |
| ---------------------- | --------------------------------------------- |
| `now()`                | 调用方省略 `now` 时提供时间值。                           |
| `difference(from, to)` | 返回模型使用的经过天数。                                  |
| `add(from, days)`      | 将最终的天数间隔转换为到期时间。                              |
| `compare(left, right)` | 可选的精确时间比较，返回负数、零或正数；Date 和 Temporal 预设均提供此操作。 |

## normalize 的作用

`normalize` 是一个 `ChronoTimeNormalizer` Standard Schema，输出类型为 `ChronoNormalizedTime<Time>`：`{ previous: Time | null, current: Time }`。`defineChrono` 既接受兼容的 schema，也接受返回 `{ value }` 或 `{ issues }` 的校验回调。`previous: null` 表示没有上一次事件。

`normalize` 将 Chrono 的具体时间字段转换为 `{ previous, current }`，让调度器无需知道 card 或 revlog 的字段名，就能计算经过天数并在撤销时恢复时间字段。复习时，它接收 `{ card, time: now }`（没有 card 字段的 Chrono 只接收 `{ time }`）；撤销时，它接收 `{ revlog }`。

对于 Date 和 Temporal，`previous` 是 `lastReviewAt`，`current` 是 `dueAt`，而非本次复习时间 `now`。Numeric 不存储时间字段，返回 `{ previous: 0, current: time }`。具体映射由 Chrono 实现决定；复习与撤销流程见 [Date](https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/guide/chrono/date.md)。

`normalize` 负责读取时间表示，`defaultValue` 负责将调度器给出的时间值写回具体的 card 和 revlog 字段。两者共同使调度器与存储字段名解耦。

## 用 defineChrono 自定义经过天数

下面的示例保留 Date 预设的 schema、normalize、默认值和精确比较，只将经过时间改为按固定 24 小时计算的小数天数。复用这些部分，可以保留输入校验以及 card/revlog 的字段约定。如果需要改变存储字段，应一并定义对应的 schema、复习与撤销 normalize，以及默认值。

如果只需要小数天数，内置的 `dateChrono.create({ config: { fractionalDays: true } })` 已支持该行为。以下自定义示例用于演示如何通过 `defineChrono` 覆盖操作。

```ts twoslash file="../../../snippets/run-code/chrono.ts" fold height=420
import { dateChrono, defineChrono } from 'ts-fsrs'

const millisecondsPerDay = 86_400_000

// Keep Date validation, card/revlog fields, and time normalization from the preset.
const fractionalDateChrono = defineChrono({
  schema: dateChrono.schema,
  normalize: dateChrono.normalize,
  defaultValue: dateChrono.defaultValue,
  create(ctx) {
    return {
      ...dateChrono.create(ctx),
      difference: (from, to) =>
        (to.getTime() - from.getTime()) / millisecondsPerDay,
    }
  },
})

const from = new Date('2026-01-01T23:00:00.000Z')
const now = new Date('2026-01-02T01:00:00.000Z')
const clock = fractionalDateChrono.create({ config: { fractionalDays: false } })

console.log(
  JSON.stringify(
    {
      utcDateDifference: dateChrono
        .create({ config: { fractionalDays: false } })
        .difference(from, now),
      fractionalDifference: clock.difference(from, now),
      halfDayLater: clock.add(from, 0.5).toISOString(),
    },
    null,
    2
  )
)

```


▶ 运行代码

同样的两小时时间差，UTC 日期预设得到 `1`，自定义 Chrono 得到 `0.08333333333333333`。调用 `add(from, 0.5)` 增加十二小时，得到 1 月 2 日 11:00 UTC。

这个自定义 Chrono 计算固定时长，不处理当地日历天或夏令时。如果需要这些日历规则，选择 Temporal 预设。模型与调度策略的组合方式见[架构](https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/guide/architecture.md)。
