# 機能設計書 34-日付フォーマット

## 概要

本ドキュメントは、Nushellにおける日付フォーマット機能（format date）の設計を記述する。このコマンドはDate型をユーザー指定のフォーマット文字列に従って文字列に変換する。

### 本機能の処理概要

**業務上の目的・背景**：
日付をファイル名、ログ出力、レポート生成など様々な用途で使用する際、目的に応じたフォーマットで出力する必要がある。strftime形式のフォーマット文字列をサポートすることで、Unix系システムに慣れたユーザーに親しみやすく、かつ柔軟な日付出力を実現する。

**機能の利用シーン**：
- ファイル名に日付を含める場合（例：backup_2024-01-15.tar.gz）
- ログファイルへの日時出力
- レポートやドキュメントへの日付挿入
- ISO 8601やRFC 3339形式での日付出力

**主要な処理内容**：
1. Date型を指定されたフォーマットで文字列に変換
2. フォーマット未指定時はRFC 2822形式をデフォルトとして使用
3. ロケールに応じた月名・曜日名の出力
4. strftimeチートシートの表示（--listオプション）

**関連システム・外部連携**：
- chrono クレート（日付フォーマット）
- nu-utils クレート（ロケール取得）
- nu-protocol クレートのDate型

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

## 関連画面

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

## 機能種別

データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | Date/String | Yes | フォーマット対象の日付 | Date型または日付文字列 |
| format string | String | No | strftime形式のフォーマット文字列 | 有効なstrftimeフォーマット |
| --list | Switch | No | strftimeチートシートを表示 | - |

### 入力データソース

パイプラインからのDate/String入力

### 主要なフォーマット指定子

| 指定子 | 説明 | 例 |
|--------|------|-----|
| %Y | 4桁の年 | 2024 |
| %m | 月（01-12） | 03 |
| %d | 日（01-31） | 15 |
| %H | 時（00-23） | 14 |
| %M | 分（00-59） | 30 |
| %S | 秒（00-59） | 45 |
| %+ | RFC 3339形式 | 2024-03-15T14:30:45+09:00 |
| %J | 連結日付（YYYYMMDD）※カスタム | 20240315 |
| %Q | 連結時刻（HHMMSS）※カスタム | 143045 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | String | フォーマットされた日付文字列 |
| list result | Table | strftimeチートシートテーブル |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. --listフラグの確認
   └─ フラグあり → strftimeチートシートを返却
2. ロケール設定の取得
   └─ 環境変数（LC_ALL, LC_TIME, LANG）から取得
3. 入力値の取得と型判定
   └─ Date型またはString型を受け付け
4. フォーマット文字列の確認
   └─ 未指定の場合はRFC 2822形式を使用
5. カスタムフォーマット指定子の処理
   └─ %J, %Q を標準形式に変換
6. 日付のフォーマット実行
   └─ chrono::format_localized() を使用
7. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{--listフラグ?}
    B -->|Yes| C[チートシート生成]
    C --> D[テーブル返却]
    B -->|No| E[ロケール取得]
    E --> F{入力が空?}
    F -->|Yes| G[PipelineEmptyエラー]
    F -->|No| H{フォーマット指定?}
    H -->|No| I[RFC 2822形式]
    H -->|Yes| J[カスタム指定子変換]
    I --> K[format_localized実行]
    J --> K
    K --> L{フォーマット成功?}
    L -->|Yes| M[文字列返却]
    L -->|No| N[TypeMismatchエラー]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-1 | デフォルトフォーマット | フォーマット未指定時はRFC 2822形式 | フォーマット引数なし |
| BR-34-2 | ロケール優先順位 | LC_ALL > LC_TIME > LANG | ロケール決定時 |
| BR-34-3 | カスタム指定子 | %J=YYYYMMDD, %Q=HHMMSS | 連結形式が必要な場合 |
| BR-34-4 | RFC 2822年制限 | 年が0-9999の範囲でないとエラー | RFC 2822形式使用時 |

### 計算ロジック

- カスタムフォーマット変換: `%J` → `%Y%m%d`, `%Q` → `%H%M%S`
- ロケール適用: chrono::format_localized()を使用

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PipelineEmpty | 入力エラー | パイプライン入力が空 | 入力を提供する |
| OnlySupportsThisInputType | 型エラー | Date/String以外の入力 | 正しい型を入力 |
| TypeMismatch | フォーマットエラー | 無効なフォーマット文字列 | 正しいフォーマットを使用 |
| GenericError | フォーマットエラー | RFC 2822で年が範囲外 | RFC 3339形式を使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 単一日付のフォーマットは即座に完了
- リスト入力に対してはmap処理で効率的に実行

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

- 環境変数（ロケール設定）の読み取りのみ
- 外部システムへのアクセスなし

## 備考

- const実行をサポート（コンパイル時評価可能）
- strftimeチートシートは`format date --list`で確認可能
- NU_TEST_LOCALE_OVERRIDE環境変数でテスト時のロケールを上書き可能

---

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

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

### 推奨読解順序

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

NushellのDate型とchronoのフォーマット機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | date.rs | `crates/nu-command/src/strings/format/date.rs` | FormatDateコマンドの全体構造 |

**読解のコツ**: chronoのformat_localized関数がコア機能。Locale型でローカライズ対応。

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

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

**主要処理フロー**:
1. **93-126行目**: run関数でロケール取得とパイプライン処理
2. **108-123行目**: 環境変数からのロケール決定ロジック
3. **163-190行目**: run関数で--listフラグとフォーマット処理
4. **192-218行目**: format_from関数でchronoフォーマット実行

#### Step 3: フォーマット処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | date.rs | `crates/nu-command/src/strings/format/date.rs` | format_from, format_helper関数 |

**主要処理フロー**:
- **203-205行目**: カスタムフォーマット指定子（%J, %Q）の変換
- **206行目**: format_localized()呼び出し
- **249-307行目**: format_helper_rfc2822関数でデフォルトフォーマット

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

```
FormatDate::run()
    │
    ├─ call.has_flag("list")
    │      │
    │      └─ [true] → generate_strftime_list()
    │
    ├─ ロケール取得
    │      ├─ stack.get_env_var("LC_ALL")
    │      ├─ stack.get_env_var("LC_TIME")
    │      └─ stack.get_env_var("LANG")
    │
    └─ input.map(format_helper/format_helper_rfc2822)
           │
           ├─ [Value::Date] → format_from()
           │                       │
           │                       └─ date_time.format_localized()
           │
           └─ [Value::String] → parse_date_from_string()
                                      │
                                      └─ format_from()
```

### データフロー図

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

Date/String ───▶ FormatDate::run() ───▶ String
    │                  │
    │                  ├─ ロケール取得
    │                  │
    │                  ├─ フォーマット文字列処理
    │                  │
    │                  └─ format_localized()
    │
フォーマット ──────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| date.rs | `crates/nu-command/src/strings/format/date.rs` | ソース | format date コマンド実装 |
| utils.rs | `crates/nu-command/src/date/utils.rs` | ソース | generate_strftime_list関数、parse_date_from_string関数 |
| mod.rs | `crates/nu-command/src/strings/format/mod.rs` | ソース | formatモジュール定義 |
