# 機能設計書: monotimes - モノトニック時間

## 1. 機能概要

### 1.1 目的
monotimesモジュールは、単調増加するタイムスタンプ（モノトニック時間）を提供する。システム時刻の調整（NTP同期など）の影響を受けず、経過時間の計測に適した時間表現を提供する。

### 1.2 機能範囲
- モノトニックタイムスタンプの取得
- タイムスタンプ間の経過時間（Duration）の計算
- タイムスタンプの比較
- Duration との加算・減算

### 1.3 関連コンポーネント
- `times` モジュール: Duration型を使用

## 2. データ構造

### 2.1 型定義

```nim
type
  MonoTime* = object  ## モノトニックタイムスタンプ
    ticks: int64      ## ナノ秒単位の内部表現
```

### 2.2 特徴
- **単調増加保証**: `getMonoTime()`を連続して呼び出した場合、後の値は常に前の値以上
- **ナノ秒精度**: 内部表現はナノ秒単位（ただし実際の精度はプラットフォーム依存）
- **相対時間**: 特定の基準点からの経過時間であり、人間可読な日時には変換不可

## 3. 主要機能

### 3.1 タイムスタンプ取得

#### getMonoTime
```nim
proc getMonoTime*(): MonoTime {.tags: [TimeEffect].}
```
- **目的**: 現在のモノトニックタイムスタンプを取得
- **戻り値**: MonoTime型のタイムスタンプ
- **ソース位置**: `lib/std/monotimes.nim:89-120`

**プラットフォーム別実装**:

| プラットフォーム | API | 精度 |
|----------------|-----|------|
| JavaScript (Node.js) | `process.hrtime()` | ナノ秒 |
| JavaScript (ブラウザ) | `window.performance.now()` | ミリ秒 |
| macOS | `mach_absolute_time()` | ナノ秒 |
| Zephyr RTOS | `k_uptime_ticks()` | システム依存 |
| POSIX | `clock_gettime(CLOCK_MONOTONIC)` | ナノ秒 |
| Windows | `QueryPerformanceCounter()` | システム依存 |

### 3.2 値の取得

#### ticks
```nim
proc ticks*(t: MonoTime): int64
```
- **目的**: 生のticks値を取得（ナノ秒単位）
- **ソース位置**: `lib/std/monotimes.nim:122-125`

### 3.3 演算

#### 減算（Duration計算）
```nim
proc `-`*(a, b: MonoTime): Duration
```
- **目的**: 2つのMonoTime間の経過時間をDurationとして取得
- **ソース位置**: `lib/std/monotimes.nim:130-132`

#### Duration加算
```nim
proc `+`*(a: MonoTime, b: Duration): MonoTime
```
- **目的**: MonoTimeにDurationを加算
- **ソース位置**: `lib/std/monotimes.nim:134-136`

#### Duration減算
```nim
proc `-`*(a: MonoTime, b: Duration): MonoTime
```
- **目的**: MonoTimeからDurationを減算
- **ソース位置**: `lib/std/monotimes.nim:138-140`

### 3.4 比較

```nim
proc `<`*(a, b: MonoTime): bool   ## aがbより前か
proc `<=`*(a, b: MonoTime): bool  ## aがb以前か
proc `==`*(a, b: MonoTime): bool  ## aとbが同時か
```
- **ソース位置**: `lib/std/monotimes.nim:142-152`

### 3.5 境界値

```nim
proc high*(typ: typedesc[MonoTime]): MonoTime  ## 最大値
proc low*(typ: typedesc[MonoTime]): MonoTime   ## 最小値
```
- **ソース位置**: `lib/std/monotimes.nim:154-160`

## 4. 使用例

```nim
import std/monotimes
import std/times

# 経過時間の計測
let start = getMonoTime()
# ... 処理 ...
let finish = getMonoTime()
let elapsed: Duration = finish - start
echo "Elapsed: ", elapsed.inMilliseconds, " ms"

# 単調増加の保証
let a = getMonoTime()
let b = getMonoTime()
assert a <= b  # 常に真
```

## 5. コードリーディングガイド

### 5.1 推奨読解順序

1. **型定義** (41-43行目)
   - MonoTime型の構造（int64のticks）

2. **プラットフォーム固有の定義** (45-87行目)
   - macOS: `mach_absolute_time`, `mach_timebase_info`
   - JavaScript: `process.hrtime()` / `performance.now()`
   - POSIX: `clock_gettime`
   - Windows: `QueryPerformanceCounter`, `QueryPerformanceFrequency`

3. **getMonoTime実装** (89-120行目)
   - 各プラットフォームでの時間取得と正規化

4. **演算子と比較** (122-160行目)
   - ticks取得、Duration変換、比較演算

### 5.2 プログラム呼び出し階層図

```
getMonoTime() [89行目]
├── [JS Node.js]
│   └── process.hrtime()
│       └── MonoTime(ticks: seconds * 1e9 + nanoseconds)
├── [JS ブラウザ]
│   └── window.performance.now()
│       └── MonoTime(ticks: milliseconds * 1e6)
├── [macOS]
│   ├── mach_absolute_time()
│   └── mach_timebase_info()
│       └── MonoTime(ticks: ticks * numer / denom)
├── [Zephyr]
│   └── k_ticks_to_ns_floor64(k_uptime_ticks())
│       └── MonoTime(ticks: nanoseconds)
├── [POSIX]
│   └── clock_gettime(CLOCK_MONOTONIC, ts)
│       └── MonoTime(ticks: tv_sec * 1e9 + tv_nsec)
└── [Windows]
    ├── QueryPerformanceCounter(ticks)
    └── QueryPerformanceFrequency(freq)
        └── MonoTime(ticks: ticks * (1e9 / freq))
```

### 5.3 データフロー図

```
[プラットフォームAPI]
        │
        ▼
┌─────────────────────────────┐
│  getMonoTime()              │
│  ┌───────────────────────┐  │
│  │ プラットフォーム検出    │  │
│  └───────────┬───────────┘  │
│              │               │
│  ┌───────────▼───────────┐  │
│  │ ナノ秒への正規化       │  │
│  └───────────┬───────────┘  │
└──────────────┼───────────────┘
               │
               ▼
         MonoTime(ticks)
               │
               ├── `-`(a, b) ──► Duration
               │
               ├── `+`(a, dur) ──► MonoTime
               │
               └── 比較演算 ──► bool
```

### 5.4 読解のコツ

- **オーバーフロー対策**: JavaScript版では`{.push overflowChecks: off.}`でオーバーフローチェックを無効化（issue #6752対応）
- **周波数変換**: WindowsとmacOSではシステム固有のtick周波数をナノ秒に変換
- **timesモジュール依存**: `Duration`型と`initDuration`は`times`モジュールからインポート

## 6. 関連ファイル一覧

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| `lib/std/monotimes.nim` | ソース | メイン実装 |
| `lib/pure/times.nim` | ソース | Duration型定義 |
| `lib/posix/posix.nim` | ソース | POSIX API定義 |

## 7. 設計上の考慮事項

### 7.1 Time型との違い

| 特性 | MonoTime | Time |
|------|----------|------|
| 用途 | 経過時間計測 | 絶対日時 |
| 単調増加 | 保証される | 保証されない |
| システム時刻調整 | 影響なし | 影響あり |
| 人間可読変換 | 不可 | 可能 |

### 7.2 精度に関する注意
- 内部表現はナノ秒だが、実際の精度はプラットフォームとハードウェアに依存
- ブラウザJavaScriptではミリ秒精度に制限される場合がある
- セキュリティ上の理由でブラウザが精度を制限することがある（Spectre対策）

### 7.3 使用上の推奨
- パフォーマンス計測には`times.Time`ではなく`MonoTime`を使用
- 長時間（年単位）の計測には注意（オーバーフローの可能性）
