# 機能設計書 42-日付・数値フォーマット設定

## 概要

本ドキュメントは、Actualの「日付・数値フォーマット設定」機能の設計内容を記載する。数値の表示形式（桁区切り、小数点）、日付の表示形式、週の開始曜日の設定について、処理内容とUIコンポーネントの仕様を定義する。

### 本機能の処理概要

日付・数値フォーマット設定機能は、アプリケーション全体で使用される数値と日付の表示形式を制御する。この設定は予算データの保存方法には影響せず、表示のみを変更する。

**業務上の目的・背景**：ユーザーの地域や個人の好みに応じた数値・日付表示形式を提供することで、データの視認性を向上させる。異なる地域のフォーマット規約（米国式、欧州式、インド式など）に対応し、グローバルなユーザー基盤をサポートする。

**機能の利用シーン**：初期セットアップ時に地域に適したフォーマットを選択する場合、海外移住などで表示形式を変更したい場合、カレンダーの週開始日を月曜日に変更したい場合に利用される。

**主要な処理内容**：
1. 数値フォーマットの選択（5種類：comma-dot, dot-comma, space-comma, apostrophe-dot, comma-dot-in）
2. 小数点以下の表示/非表示の切り替え
3. 日付フォーマットの選択（6種類：MM/dd/yyyy, dd/MM/yyyy, yyyy-MM-dd, MM.dd.yyyy, dd.MM.yyyy, dd-MM-yyyy）
4. 週の開始曜日の選択（日曜日〜土曜日）
5. 同期設定への保存と即時反映

**関連システム・外部連携**：なし

**権限による制御**：特になし（全ユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 40 | 設定画面 | 主機能 | 日付形式・数値区切りの設定 |

## 機能種別

設定・表示フォーマット処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| numberFormat | NumberFormats | No | 数値表示形式 | 'comma-dot' / 'dot-comma' / 'space-comma' / 'apostrophe-dot' / 'comma-dot-in' のいずれか |
| hideFraction | string | No | 小数点以下を非表示にするか | 'true' / 'false' |
| dateFormat | string | No | 日付表示形式 | 'MM/dd/yyyy' / 'dd/MM/yyyy' / 'yyyy-MM-dd' / 'MM.dd.yyyy' / 'dd.MM.yyyy' / 'dd-MM-yyyy' のいずれか |
| firstDayOfWeekIdx | string | No | 週の開始曜日インデックス | '0'〜'6'（0=日曜日、1=月曜日、...、6=土曜日） |

### 入力データソース

- 画面入力（ドロップダウン選択、チェックボックス）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| numberFormat | string | 選択された数値表示形式 |
| hideFraction | string | 小数点以下の表示/非表示設定 |
| dateFormat | string | 選択された日付表示形式 |
| firstDayOfWeekIdx | string | 週の開始曜日インデックス |

### 出力先

- 同期設定（SyncedPrefs）- デバイス間で同期される

## 処理フロー

### 処理シーケンス

```
1. 設定画面のFormatSettingsコンポーネント表示
   └─ useSyncedPrefフックで現在の設定値を取得

2. 数値フォーマット変更
   ├─ Selectコンポーネントで選択
   ├─ setNumberFormatPref呼び出し
   └─ 同期設定に保存

3. 小数点表示切替
   ├─ Checkboxの変更検知
   ├─ setHideFractionPref呼び出し
   └─ 同期設定に保存

4. 日付フォーマット変更
   ├─ Selectコンポーネントで選択
   ├─ setDateFormatPref呼び出し
   └─ 同期設定に保存

5. 週開始曜日変更
   ├─ Selectコンポーネントで選択
   ├─ setFirstDayOfWeekIdxPref呼び出し
   └─ 同期設定に保存

6. アプリケーション全体への反映
   └─ getNumberFormat/useDateFormatで設定を参照し表示に反映
```

### フローチャート

```mermaid
flowchart TD
    A[設定画面表示] --> B[現在の設定値読み込み]
    B --> C{ユーザー操作}

    C -->|数値フォーマット変更| D[setNumberFormatPref]
    C -->|小数点表示切替| E[setHideFractionPref]
    C -->|日付フォーマット変更| F[setDateFormatPref]
    C -->|週開始曜日変更| G[setFirstDayOfWeekIdxPref]

    D --> H[saveSyncedPrefs dispatch]
    E --> H
    F --> H
    G --> H

    H --> I[同期設定に保存]
    I --> J[Redux状態更新]
    J --> K[UI即時反映]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | デフォルト数値形式 | デフォルトは'comma-dot'（米国式：1,000.33） | 未設定時 |
| BR-42-02 | デフォルト日付形式 | デフォルトは'MM/dd/yyyy' | 未設定時 |
| BR-42-03 | デフォルト週開始 | デフォルトは'0'（日曜日） | 未設定時 |
| BR-42-04 | 小数点非表示 | hideFraction='true'の場合、金額の小数点以下を表示しない | 該当設定時 |
| BR-42-05 | データ非影響 | フォーマット設定は表示のみ変更、データ保存形式には影響しない | 常時 |

### 数値フォーマット詳細

| 形式 | 表示例 | 小数点なし例 | ロケール |
|-----|--------|-------------|---------|
| comma-dot | 1,000.33 | 1,000 | en-US |
| dot-comma | 1.000,33 | 1.000 | de-DE |
| space-comma | 1 000,33 | 1 000 | fr-FR |
| apostrophe-dot | 1'000.33 | 1'000 | de-CH |
| comma-dot-in | 1,00,000.33 | 1,00,000 | en-IN |

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

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

本機能はSyncedPrefsを通じて設定を保存する。実際の保存先は予算ファイルのメタデータテーブル。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| フォーマット変更 | prefs | UPDATE | 各フォーマット設定を更新 |

### 設定キー詳細

| キー | 型 | 説明 |
|-----|-----|------|
| numberFormat | string | 数値フォーマット種別 |
| hideFraction | string | 小数点以下非表示フラグ |
| dateFormat | string | 日付フォーマット種別 |
| firstDayOfWeekIdx | string | 週開始曜日インデックス |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 通常のドロップダウン選択のため発生しない | - |

### リトライ仕様

なし（設定変更は即座に保存される）

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

設定変更は個別に保存され、トランザクション処理は不要。失敗時は前回の値が維持される。

## パフォーマンス要件

- 設定変更: 即座に反映（100ms以内）
- フォーマット適用: 各表示箇所で都度計算（通常1ms以内）

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

特になし（表示設定のみで、センシティブなデータを扱わない）

## 備考

- 数値フォーマットは通貨表示、予算金額、取引金額など、アプリケーション内のすべての金額表示に適用される
- 日付フォーマットは取引日、予算期間、レポート期間など、すべての日付表示に適用される
- 週開始曜日はカレンダー表示（Pikaday）に影響する

---

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

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

### 推奨読解順序

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

フォーマット設定で使用されるデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | util.ts | `packages/loot-core/src/shared/util.ts` | NumberFormats型とnumberFormats配列（258-287行目） |
| 1-2 | prefs.d.ts | `packages/loot-core/src/types/prefs.d.ts` | SyncedPrefsのフォーマット関連定義 |

**読解のコツ**: NUMBER_FORMATS定数で許可される数値フォーマットが定義されている。各フォーマットには対応するロケールがある（comma-dot→en-US、dot-comma→de-DE等）。

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

フォーマット設定UIのエントリーポイントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Format.tsx | `packages/desktop-client/src/components/settings/Format.tsx` | FormatSettingsコンポーネント全体の構造（51-143行目） |

**主要処理フロー**:
1. **24-41行目**: useDaysOfWeekフックで曜日選択オプションを生成
2. **42-49行目**: dateFormats配列で日付フォーマットオプション定義
3. **55-62行目**: useSyncedPrefフックで各設定値を取得
4. **72-142行目**: UIレンダリング（Numbers, Dates, First day of the weekの3カラム）

#### Step 3: 設定保存の仕組みを理解する

同期設定の読み書きフックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | useSyncedPref.ts | `packages/desktop-client/src/hooks/useSyncedPref.ts` | 同期設定の読み書きフック（12-29行目） |

**主要処理フロー**:
- **16-25行目**: setPref関数がsaveSyncedPrefsアクションをdispatch
- **26行目**: Redux stateからpref値を取得

#### Step 4: フォーマット適用ロジックを理解する

数値フォーマットの適用処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | util.ts | `packages/loot-core/src/shared/util.ts` | getNumberFormat関数の実装（314-365行目） |

**主要処理フロー**:
- **289-295行目**: numberFormatConfig変数でグローバル設定を保持
- **297-308行目**: parseNumberFormat関数で設定文字列をパース
- **310-312行目**: setNumberFormat関数でグローバル設定を更新
- **331-356行目**: switch文でフォーマット種別ごとにロケールと区切り文字を決定

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

```
FormatSettings (Format.tsx)
    │
    ├─ useSyncedPref('firstDayOfWeekIdx')
    │      └─ useSelector(state.prefs.synced.firstDayOfWeekIdx)
    │
    ├─ useDateFormat() → useSyncedPref('dateFormat')
    │
    ├─ useSyncedPref('numberFormat')
    │
    ├─ useSyncedPref('hideFraction')
    │
    ├─ setNumberFormatPref()
    │      └─ dispatch(saveSyncedPrefs({prefs: {numberFormat: value}}))
    │
    ├─ setDateFormatPref()
    │      └─ dispatch(saveSyncedPrefs({prefs: {dateFormat: value}}))
    │
    ├─ setHideFractionPref()
    │      └─ dispatch(saveSyncedPrefs({prefs: {hideFraction: value}}))
    │
    └─ setFirstDayOfWeekIdxPref()
           └─ dispatch(saveSyncedPrefs({prefs: {firstDayOfWeekIdx: value}}))

getNumberFormat (util.ts)
    └─ フォーマット設定に基づき locale, thousandsSeparator, decimalSeparator を決定
```

### データフロー図

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

数値フォーマット         setNumberFormatPref()
選択 ─────────────────▶  saveSyncedPrefs() ──────────▶ SyncedPrefs
                                                        (numberFormat)

小数点非表示             setHideFractionPref()
チェック ────────────▶  saveSyncedPrefs() ──────────▶ SyncedPrefs
                                                        (hideFraction)

日付フォーマット         setDateFormatPref()
選択 ─────────────────▶  saveSyncedPrefs() ──────────▶ SyncedPrefs
                                                        (dateFormat)

週開始曜日               setFirstDayOfWeekIdxPref()
選択 ─────────────────▶  saveSyncedPrefs() ──────────▶ SyncedPrefs
                                                        (firstDayOfWeekIdx)

SyncedPrefs              getNumberFormat()
(numberFormat,           (util.ts)
hideFraction) ──────────▶ ─────────────────────────────▶ フォーマット済み
                                                         金額表示

SyncedPrefs              useDateFormat()
(dateFormat) ───────────▶ ─────────────────────────────▶ フォーマット済み
                                                         日付表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Format.tsx | `packages/desktop-client/src/components/settings/Format.tsx` | ソース | フォーマット設定UIコンポーネント |
| useSyncedPref.ts | `packages/desktop-client/src/hooks/useSyncedPref.ts` | ソース | 同期設定読み書きフック |
| useDateFormat.ts | `packages/desktop-client/src/hooks/useDateFormat.ts` | ソース | 日付フォーマット取得フック |
| util.ts | `packages/loot-core/src/shared/util.ts` | ソース | 数値フォーマットユーティリティ |
| UI.tsx | `packages/desktop-client/src/components/settings/UI.tsx` | ソース | 設定画面共通UIコンポーネント |
| Checkbox.tsx | `packages/desktop-client/src/components/forms.tsx` | ソース | チェックボックスコンポーネント |
