# 機能設計書 33-日付パース

## 概要

本ドキュメントは、Nushellにおける日付パース機能（date from-human）の設計を記述する。このコマンドは人間が読みやすい形式の日付文字列を構造化されたDate型に変換する。

### 本機能の処理概要

**業務上の目的・背景**：
日常的に使用する自然言語に近い日付表現（「今日」「明日」「先週の金曜日」等）を、プログラムで扱えるDate型に変換する機能は、ユーザーフレンドリーなシェル環境の実現に不可欠である。厳密なISO形式を要求せず、直感的な入力を可能にすることで、スクリプト作成の効率を向上させる。

**機能の利用シーン**：
- 「3日後」のファイルを検索する場合
- 「先週の金曜日」のログを取得する場合
- 相対的な時間指定でのタスクスケジューリング
- ユーザー入力からの日付解析

**主要な処理内容**：
1. 自然言語風の日付文字列を解析
2. 現在時刻を基準とした相対日付の計算
3. 構造化されたDate型への変換
4. サポートされるフォーマット例の一覧表示（--listオプション）

**関連システム・外部連携**：
- human_date_parser クレート（自然言語日付パース）
- chrono クレート（日付・時刻処理）
- nu-protocol クレートのDate型

**権限による制御**：
特になし。すべてのユーザーが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 参照画面 | コマンド入力・結果表示 |

## 機能種別

データ変換 / パース処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String | Yes | パース対象の日付文字列 | 文字列型 |
| --list | Switch | No | サポートフォーマット例を表示 | - |

### 入力データソース

パイプラインからの文字列入力

### サポートされる日付フォーマット例

- `Today 18:30`
- `2022-11-07 13:25:30`
- `15:20 Friday`
- `This Friday 17:00`
- `13:25, Next Tuesday`
- `Last Friday at 19:45`
- `In 3 days`
- `In 2 hours`
- `10 hours and 5 minutes ago`
- `1 years ago`
- `A year ago` / `A month ago` / `A week ago`
- `A day ago` / `An hour ago` / `A minute ago`
- `Now`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Date | パースされた日時 |
| list result | Table | フォーマット例とパース結果のテーブル |

### 出力先

パイプライン出力（次のコマンドへ）

## 処理フロー

### 処理シーケンス

```
1. --listフラグの確認
   └─ フラグあり → サポートフォーマット例のテーブルを返却
2. 入力文字列の取得
   └─ パイプラインから文字列を取得
3. 現在時刻の取得
   └─ Local::now() で基準時刻を設定
4. human_date_parserによるパース
   └─ from_human_time() でパース実行
5. ParseResultの型に応じた処理
   └─ Date/DateTime/Time それぞれの処理
6. タイムゾーン付きDate値の生成
   └─ ローカルオフセットを適用
7. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{--listフラグ?}
    B -->|Yes| C[フォーマット例テーブル生成]
    C --> D[テーブル返却]
    B -->|No| E{入力が空?}
    E -->|Yes| F[PipelineEmptyエラー]
    E -->|No| G[現在時刻取得]
    G --> H[from_human_time実行]
    H --> I{パース成功?}
    I -->|No| J[IncorrectValueエラー]
    I -->|Yes| K{結果の型?}
    K -->|Date| L[日付+現在時刻で生成]
    K -->|DateTime| M[DateTimeをそのまま使用]
    K -->|Time| N[今日の日付+時刻で生成]
    L --> O[Date値返却]
    M --> O
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-33-1 | 相対日付の基準 | 現在のローカル時刻を基準とする | 相対日付表現の解析時 |
| BR-33-2 | 時刻省略時 | 時刻が省略された場合は現在の時刻を使用 | Dateのみのパース結果時 |
| BR-33-3 | 日付省略時 | 日付が省略された場合は今日の日付を使用 | Timeのみのパース結果時 |
| BR-33-4 | タイムゾーン | ローカルタイムゾーンを適用 | 全ての変換時 |

### 計算ロジック

- 相対日付計算: human_date_parserライブラリに委譲
- タイムゾーン適用: chrono::Local::now().offset() を使用

## データベース操作仕様

### 操作別データベース影響一覧

該当なし（データベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PipelineEmpty | 入力エラー | パイプライン入力が空 | 入力を提供する |
| OnlySupportsThisInputType | 型エラー | String以外の入力 | 文字列を入力 |
| IncorrectValue | パースエラー | 日付として解析できない | 正しいフォーマットを使用 |
| DatetimeParseError | パースエラー | 曖昧または無効な日時 | より明確な表現を使用 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- 文字列パースは即座に完了
- リスト入力に対してはmap処理で効率的に実行

## セキュリティ考慮事項

- 入力文字列のサニタイズは不要（内部処理のみ）
- システム時刻へのアクセスのみ

## 備考

- human_date_parserライブラリの機能に依存
- 英語の日付表現に最適化されている
- `--list`オプションでサポートされるフォーマットを確認可能

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

human_date_parserのParseResult型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | from_human.rs | `crates/nu-command/src/date/from_human.rs` | ParseResult enum（Date/DateTime/Time） |

**読解のコツ**: human_date_parserはパース結果を3種類（日付のみ、日時、時刻のみ）で返す。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | from_human.rs | `crates/nu-command/src/date/from_human.rs` | DateFromHumanコマンドの実装 |

**主要処理フロー**:
1. **45-61行目**: run関数で--listフラグ確認とパイプライン処理
2. **89-104行目**: helper関数で入力型判定
3. **106-154行目**: from_human_timeの結果に応じた分岐処理
4. **213-249行目**: list_human_readable_examples関数でフォーマット例生成

#### Step 3: パース結果の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | from_human.rs | `crates/nu-command/src/date/from_human.rs` | ParseResult型別の処理（110-153行目） |

**主要処理フロー**:
- **110-117行目**: ParseResult::Date の場合 - 現在時刻と組み合わせ
- **119-142行目**: ParseResult::DateTime の場合 - そのまま使用
- **144-152行目**: ParseResult::Time の場合 - 今日の日付と組み合わせ

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

```
DateFromHuman::run()
    │
    ├─ call.has_flag("list")
    │      │
    │      └─ [true] → list_human_readable_examples()
    │
    └─ input.map(helper)
           │
           ├─ [Value::String] → from_human_time()
           │                       │
           │                       ├─ ParseResult::Date → 現在時刻を追加
           │                       │
           │                       ├─ ParseResult::DateTime → そのまま使用
           │                       │
           │                       └─ ParseResult::Time → 今日の日付を追加
           │
           └─ [Other] → OnlySupportsThisInputTypeエラー
```

### データフロー図

```
[入力]               [処理]                    [出力]

String ─────────▶ DateFromHuman::run() ───▶ Date
"Today 18:30"          │
                       ├─ from_human_time()
                       │
                       ├─ ParseResult判定
                       │
                       └─ ローカルTZ適用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| from_human.rs | `crates/nu-command/src/date/from_human.rs` | ソース | date from-human コマンド実装 |
| mod.rs | `crates/nu-command/src/date/mod.rs` | ソース | dateモジュール定義（DateFromHumanのエクスポート） |
