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

# Chrono の概要

Chrono は、スケジューラーが時間をどう表現し、経過日数と次の復習日時をどう計算するかを定めます。モデルは日単位の間隔を扱い、Chrono がその間隔をアプリケーションの時刻値に結び付けます。

## プリセットを選ぶ

`dateChrono`、`numericChrono`、`temporalInstantChrono`、`defineChrono` は `ts-fsrs` からインポートできます。

| プリセット                   | 時刻値                | 日数の計算                                                                                                    |
| ----------------------- | ------------------ | -------------------------------------------------------------------------------------------------------- |
| `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/ja-JP/guide/chrono/date.md)、[Numeric](https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/chrono/numeric.md)、[Temporal Instant](https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/chrono/temporal-instant.md)。

## 定義と実行時の操作

`Chrono` の定義には `schema`、`normalize`、`defaultValue`、`create` が含まれます。定義を `defineScheduler({ model, chrono })` に渡します。時間演算だけを使いたい場合は、定義の `create({ config })` を呼び出してください。設定済みの実行時オブジェクトには `scheduler.chrono` からもアクセスできます。

Date と Temporal の `create({ config })` には完全な設定を渡してください。引数なしの `create()` は Numeric など設定が不要なプリセットで使えます。スケジューラーの生成時には設定の検証と 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` は互換性のあるスキーマ、または `{ 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/ja-JP/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
  )
)

```


▶ コードを実行

同じ2時間の差でも、UTC 日付のプリセットでは `1`、カスタム Chrono では `0.08333333333333333` になります。`add(from, 0.5)` は12時間を加算し、1月2日 11:00 UTC を返します。

このカスタム Chrono は固定の経過時間を計算し、現地の暦日や夏時間は扱いません。こうした暦のルールが必要な場合は Temporal プリセットを選んでください。モデルとスケジューリングポリシーの組み合わせ方は[アーキテクチャ](https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/architecture.md)を参照してください。
