> For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/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-TW/guide/chrono/date.md)、[Numeric](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/chrono/numeric.md)、[Temporal Instant](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/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-TW/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-TW/guide/architecture.md)。
