# 機能設計書 74-DateTimeFormatInfo

## 概要

本ドキュメントは、VBCorLibライブラリにおけるDateTimeFormatInfoクラスの機能設計を記載する。DateTimeFormatInfoは、日付と時刻の書式設定に必要なカルチャ固有の情報を提供するクラスである。

### 本機能の処理概要

DateTimeFormatInfoは、特定のロケールにおける日付と時刻の書式設定情報を格納し、CorDateTimeやDate値のフォーマッティングに使用されるクラスである。IFormatProviderインターフェースを実装し、日付時刻の書式設定オブジェクトとして機能する。曜日名、月名、AM/PM表記、日付区切り文字、時刻区切り文字、各種書式パターンなど、国際化対応に必要な情報を一元管理する。

**業務上の目的・背景**：日付と時刻の表示形式は国・地域によって大きく異なる。米国では「MM/dd/yyyy」、日本では「yyyy/MM/dd」、ドイツでは「dd.MM.yyyy」など、同じ日付でも表記が異なる。また、月名や曜日名も言語によって異なる。DateTimeFormatInfoクラスは、これらの地域固有の設定を統一的に管理し、.NET Frameworkとの互換性を持つVB6実装を提供することで、既存資産の移植性を向上させる。

**機能の利用シーン**：多言語対応アプリケーションでの日付表示、レポート出力における地域固有日付フォーマット、ログファイルの日時記録、国際的なデータ交換における日付変換などで利用される。

**主要な処理内容**：
1. 曜日名・月名の取得（フル名称・省略名称）
2. 日付・時刻の書式パターンの管理（Short/Long Date/Time Pattern）
3. AM/PM表記、日付区切り文字、時刻区切り文字の管理
4. カレンダー週ルールと週の開始曜日の設定
5. CorDateTimeオブジェクトのフォーマッティング
6. IFormatProviderインターフェースによる書式プロバイダ機能

**関連システム・外部連携**：CultureInfoクラスと連携してカルチャ固有の日付時刻フォーマット情報を提供する。Calendarクラスと連携して日付計算の基盤となる。

**権限による制御**：特になし。ただし、ReadOnlyフラグにより変更不可のインスタンスを作成可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面を持たないユーティリティクラス |

## 機能種別

データ提供処理（日付時刻書式情報管理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| LCID | Long | Yes | ロケール識別子 | 有効なLCIDであること |
| UseUserOverride | Boolean | No | ユーザー設定を使用するか | デフォルトはTrue |
| Calendar | Calendar | No | 使用するカレンダー | Nothingの場合はGregorianCalendar |

### 入力データソース

- CultureTableクラスからロードされる日付時刻書式定義データ
- Windows APIから取得されるユーザーロケール設定（UseUserOverride時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| AbbreviatedDayNames | String() | 省略曜日名配列（7要素） |
| AbbreviatedMonthNames | String() | 省略月名配列（13要素） |
| DayNames | String() | 曜日名配列（7要素） |
| MonthNames | String() | 月名配列（13要素） |
| AMDesignator | String | 午前表記（例: "AM"） |
| PMDesignator | String | 午後表記（例: "PM"） |
| DateSeparator | String | 日付区切り文字（例: "/"） |
| TimeSeparator | String | 時刻区切り文字（例: ":"） |
| FirstDayOfWeek | DayOfWeek | 週の開始曜日 |
| CalendarWeekRule | CalendarWeekRule | 年の最初の週の定義 |
| ShortDatePattern | String | 短い日付パターン（例: "M/d/yyyy"） |
| LongDatePattern | String | 長い日付パターン |
| ShortTimePattern | String | 短い時刻パターン |
| LongTimePattern | String | 長い時刻パターン |
| FullDateTimePattern | String | 完全日時パターン |
| MonthDayPattern | String | 月日パターン |
| YearMonthPattern | String | 年月パターン |
| RFC1123Pattern | String | RFC1123形式パターン（固定） |
| SortableDateTimePattern | String | ソート可能日時パターン（固定） |
| UniversalSortableDateTimePattern | String | UTC日時パターン（固定） |
| Calendar | Calendar | 関連付けられたカレンダー |
| IsReadOnly | Boolean | 読み取り専用フラグ |

### 出力先

プロパティを介してアプリケーションに提供される。Formatメソッドで書式化された文字列が返却される。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタによる初期化
   └─ LCIDとUseUserOverrideフラグを受け取る
2. 共通情報のロード（LoadCommon）
   └─ 曜日名、月名、パターン配列をCultureTableから取得
3. ユーザー設定または標準設定のロード
   ├─ UseUserOverride=True: Windows APIから取得
   └─ UseUserOverride=False: CultureTableから取得
4. 日時フォーマット実行（Formatメソッド）
   ├─ 書式指定子の解釈（d, D, t, T, f, F, g, G, m, r, s, u, y）
   └─ CustomFormat関数でパターン適用
```

### フローチャート

```mermaid
flowchart TD
    A[DateTimeFormatInfo生成] --> B[Init呼び出し]
    B --> C[LoadCommon - 共通情報ロード]
    C --> D{UseUserOverride?}
    D -->|Yes| E[LoadUserOverride - Windows API]
    D -->|No| F[LoadFromCultureTable]
    E --> G[mLoaded = True]
    F --> G
    G --> H[Formatメソッド呼び出し]
    H --> I{書式指定子の長さ}
    I -->|0| J[デフォルトパターン適用]
    I -->|1| K[標準書式指定子解釈]
    I -->|2以上| L[カスタムパターンとして使用]
    J --> M[CustomFormat実行]
    K --> M
    L --> M
    M --> N[書式化された文字列返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 曜日配列サイズ | AbbreviatedDayNames/DayNamesは7要素固定 | プロパティ設定時 |
| BR-02 | 月配列サイズ | AbbreviatedMonthNames/MonthNamesは13要素固定 | プロパティ設定時 |
| BR-03 | ReadOnlyカルチャ | ReadOnlyフラグが立っている場合は変更不可 | プロパティSet時 |
| BR-04 | 遅延ロード | 初回プロパティアクセス時にロード | プロパティGet時 |
| BR-05 | FullDateTimePattern自動生成 | 明示的に設定されていない場合はLongDate+LongTimeを結合 | FullDateTimePatternGet時 |
| BR-06 | 標準パターン不変 | RFC1123, Sortable, UniversalSortableパターンは全カルチャ共通 | パターン取得時 |
| BR-07 | 月範囲 | 月は1-13の範囲（13月対応カレンダー用） | GetMonthName等 |
| BR-08 | 曜日範囲 | 曜日は0-6の範囲（0=日曜日） | GetDayName等 |

### 計算ロジック

```
書式指定子マッピング:
- d: ShortDatePattern
- D: LongDatePattern
- t: ShortTimePattern
- T: LongTimePattern
- f: LongDatePattern + " " + ShortTimePattern
- F: FullDateTimePattern
- g: ShortDatePattern + " " + ShortTimePattern
- G: ShortDatePattern + " " + LongTimePattern
- m/M: MonthDayPattern
- r/R: RFC1123Pattern（固定: "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"）
- s: SortableDateTimePattern（固定: "yyyy'-'MM'-'dd'T'HH':'mm':'ss"）
- u: UniversalSortableDateTimePattern（固定: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'"）
- y/Y: YearMonthPattern

カスタム書式指定子:
- d: 日（1桁）, dd: 日（2桁）, ddd: 省略曜日名, dddd: 曜日名
- M: 月（1桁）, MM: 月（2桁）, MMM: 省略月名, MMMM: 月名
- y: 年下2桁（1桁）, yy: 年下2桁（2桁）, yyyy: 年4桁
- h: 12時間制時（1桁）, hh: 12時間制時（2桁）
- H: 24時間制時（1桁）, HH: 24時間制時（2桁）
- m: 分（1桁）, mm: 分（2桁）
- s: 秒（1桁）, ss: 秒（2桁）
- f-fffffff: 秒の小数部（1-7桁）
- t: AM/PM（1文字）, tt: AM/PM（フル）
- z: タイムゾーンオフセット（時）, zz: 2桁, zzz: 時:分
- /: 日付区切り文字（DateSeparator）
- :: 時刻区切り文字（TimeSeparator）
```

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

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotSupported | 非サポート | CultureTableがロードされていない状態での初期化 | CultureTableを先にロード |
| ArgumentOutOfRange | 引数範囲外 | DayOfWeekが0-6の範囲外 | 有効な曜日値を指定 |
| ArgumentOutOfRange | 引数範囲外 | Monthが1-13の範囲外 | 有効な月値を指定 |
| InvalidOperation | 無効操作 | ReadOnlyインスタンスへの書き込み | Cloneで変更可能なコピーを作成 |
| ArgumentNull | Null引数 | CalendarにNullを設定 | 有効なCalendarオブジェクトを指定 |
| Argument | 引数エラー | 配列サイズが規定と異なる | 正しいサイズの配列を指定 |
| Format | 書式エラー | 無効な書式指定子 | 有効な書式指定子を使用 |
| Format | 書式エラー | 閉じていない引用符 | 引用符を正しく対応させる |

### リトライ仕様

書式設定処理は同期的に実行され、リトライ機構は不要。

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

本機能はトランザクション管理を必要としない。

## パフォーマンス要件

- 書式設定情報は初回ロード時にキャッシュされる
- StringBuilderCacheを使用した効率的な文字列構築
- AllocChars/FreeCharsによるパターン文字配列の効率的な管理

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

- ReadOnlyフラグにより、共有インスタンスの意図しない変更を防止
- ユーザー入力の書式文字列はFormatExceptionでエラーハンドリング

## 備考

- .NET FrameworkのSystem.Globalization.DateTimeFormatInfoクラスと互換性のある実装
- MITライセンスで提供（Copyright (c) 2015 Kelly Ethridge）
- PropertyBagを使用したシリアライズ/デシリアライズに対応
- エラ機能（GetEra, GetEraName, GetAbbreviatedEraName）は完全実装ではなく、常に"AD"/"A.D."を返す

---

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

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

### 推奨読解順序

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

まず、DateTimeFormatInfoが保持するプロパティ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | PropsType構造体（行84-109）で書式情報を定義 |
| 1-2 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | 固定パターン定数（行77-79）の定義 |

**読解のコツ**: PropsType内のAllXxxPatterns配列は複数のパターンを保持し、GetAllDateTimePatternsで使用される。

#### Step 2: 初期化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | Init関数（行784-797）による初期化 |
| 2-2 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | LoadCommon（行838-852）で共通情報ロード |
| 2-3 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | LoadUserOverride（行810-822）/LoadFromCultureTable（行824-836） |

**主要処理フロー**:
1. **行785-786**: CultureTableのロード確認
2. **行789**: LoadCommon呼び出し
3. **行791-795**: UseUserOverrideに応じたロード処理分岐
4. **行796**: mLoaded = True

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | Format関数（行745-748）のエントリーポイント |
| 3-2 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | GetPattern関数（行1086-1126）で書式指定子解釈 |
| 3-3 | DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | CustomFormat関数（行855-1018）でパターン適用 |

**主要処理フロー**:
- **行900-1005**: メインループでパターン文字を順次処理
- **行917-996**: 各書式指定子の処理（d, M, h, H, m, s, t, y, z等）
- **行1029-1045**: 数値の1-4桁出力ヘルパー

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

```
CorDateTime.ToString / ユーザーコード
    │
    ├─ DateTimeFormatInfo.Format(Value, FormatString)
    │      ├─ VerifyLoaded()
    │      │      └─ Init(INVARIANT_LCID, False) [未ロード時]
    │      ├─ GetPattern(FormatString)
    │      │      └─ 書式指定子 → パターン変換
    │      └─ CustomFormat(Value, Pattern)
    │             ├─ dt.GetDateParts() - 年月日取得
    │             ├─ GetRepeatCount() - パターン文字繰り返し数
    │             ├─ Append1to4CountValue() - 日/月出力
    │             ├─ Append1or2DigitNumber() - 時分秒出力
    │             └─ StringBuilderCache - 文字列構築
    │
    ├─ GetDayName(DayOfWeek)
    │      └─ mProps.DayNames(DayOfWeek)
    │
    ├─ GetMonthName(Month)
    │      └─ mProps.MonthNames(Month - 1)
    │
    └─ GetAllDateTimePatterns(Format)
           ├─ GetSpecificDateTimePattern()
           └─ CreateDateTimePatterns() [複合パターン生成]
```

### データフロー図

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

CorDateTime ───▶ Format関数 ───▶ 書式化された文字列
    │               │
    │               ├─ GetPattern（書式指定子解釈）
    │               │
    │               └─ CustomFormat（パターン適用）
    │                      │
    ▼                      ▼
日付部品取得 ◄─── 年/月/日/時/分/秒を抽出
    │
    ▼
書式パターン ───▶ パターン文字ループ処理
    │                  │
    │         ┌────────┴────────┐
    │         ▼                 ▼
    │   数値フォーマット    名前参照
    │   (d, M, y, h, m, s)  (ddd, MMM)
    │         │                 │
    │         ▼                 ▼
    │   AbbreviatedDayNames   MonthNames
    │   AbbreviatedMonthNames DayNames
    │         │                 │
    │         └────────┬────────┘
    │                  ▼
    └─────────▶ StringBuilder蓄積 ───▶ 結果文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | ソース | 日付時刻書式情報メインクラス |
| DateTimeFormatInfoStatic.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfoStatic.cls` | ソース | 静的メソッド提供クラス |
| CultureInfo.cls | `Source/CorLib/System.Globalization/CultureInfo.cls` | ソース | カルチャ情報（DateTimeFormatの親） |
| CultureTable.cls | `Source/CorLib/System.Globalization/CultureTable.cls` | ソース | カルチャデータテーブル |
| Calendar.cls | `Source/CorLib/System.Globalization/Calendar.cls` | ソース | カレンダー基底クラス |
| GregorianCalendar.cls | `Source/CorLib/System.Globalization/GregorianCalendar.cls` | ソース | デフォルトカレンダー |
| CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | ソース | 日付時刻クラス（フォーマット対象） |
| StringBuilder.cls | `Source/CorLib/System.Text/StringBuilder.cls` | ソース | 文字列構築クラス |
| IFormatProvider.cls | `Source/CorLib/System/IFormatProvider.cls` | ソース | 書式プロバイダインターフェース |
| ICloneable.cls | `Source/CorLib/System/ICloneable.cls` | ソース | クローン可能インターフェース |
