# 機能設計書 81-KoreanCalendar

## 概要

本ドキュメントは、VBCorLibライブラリにおけるKoreanCalendar（韓国暦）機能の設計を記述する。

### 本機能の処理概要

KoreanCalendarは、韓国暦（檀紀）に基づいた日付計算機能を提供するクラスである。韓国暦は紀元前2333年を元年とする紀年法で、グレゴリオ暦との相互変換や日付演算を実現する。

**業務上の目的・背景**：韓国や朝鮮半島に関連するシステムにおいて、韓国暦による日付表示や計算が必要となる場合がある。特に歴史的な文書や伝統的な行事の日付管理において、韓国暦のサポートは重要である。本機能は.NET FrameworkのSystem.Globalization.KoreanCalendarと互換性のあるAPIを提供し、VB6アプリケーションにおいて国際化対応を可能にする。

**機能の利用シーン**：
- 韓国暦を使用する業務アプリケーションでの日付表示
- グレゴリオ暦と韓国暦の相互変換
- 韓国暦に基づいた日付演算（年/月/日の加算・減算）
- うるう年の判定

**主要な処理内容**：
1. 韓国暦年とグレゴリオ暦年の相互変換（年オフセット: 2333年）
2. 日付の加算・減算（年、月、日、時、分、秒、ミリ秒単位）
3. うるう年・うるう日の判定
4. 2桁年から4桁年への変換
5. 日付からの年月日時分秒ミリ秒の抽出
6. 日付の曜日・年間通算日の取得

**関連システム・外部連携**：
- Windowsのロケール設定からTwoDigitYearMax値を取得
- CorDateTimeクラスとの連携による日付操作

**権限による制御**：特になし。ReadOnlyプロパティにより読み取り専用カレンダーインスタンスの作成が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | - | - | KoreanCalendarはライブラリ機能として他のアプリケーションから利用される |

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Time | Variant (Date/CorDateTime) | Yes | 操作対象の日時 | 有効な日付範囲内であること |
| Year | Long | Yes | 韓国暦の年（2334〜12332） | MinKoreanYear(2334)以上、MaxKoreanYear(12332)以下 |
| Month | Long | Yes | 月（1〜12） | 1〜12の範囲内 |
| Day | Long | Yes | 日 | 該当月の有効日数以内 |
| Era | Variant | No | 時代（省略時は現在の時代） | KoreanEra(1)またはCurrentEra |

### 入力データソース

- アプリケーションからのメソッド呼び出し
- Windowsシステム設定（TwoDigitYearMax初期値）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CorDateTime | CorDateTime | 変換・演算後の日時オブジェクト |
| Year | Long | 韓国暦の年 |
| Month | Long | 月 |
| DayOfMonth | Long | 日 |
| DayOfWeek | DayOfWeek | 曜日 |
| DayOfYear | Long | 年間通算日 |
| IsLeapYear | Boolean | うるう年フラグ |
| IsLeapDay | Boolean | うるう日フラグ |

### 出力先

呼び出し元アプリケーションへの戻り値

## 処理フロー

### 処理シーケンス

```
1. 入力パラメータの検証
   └─ Era、Year、Month、Dayの範囲チェック
2. 韓国暦年からグレゴリオ暦年への変換
   └─ グレゴリオ暦年 = 韓国暦年 - 2333
3. 日付演算の実行
   └─ CorDateTimeまたはCalendar共通処理を利用
4. 結果の返却
   └─ 必要に応じてグレゴリオ暦年から韓国暦年へ再変換
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{パラメータ検証}
    B -->|エラー| C[例外スロー]
    B -->|OK| D[韓国暦年→グレゴリオ暦年変換]
    D --> E[CorDateTime/Calendar共通処理呼び出し]
    E --> F{結果の年変換が必要?}
    F -->|Yes| G[グレゴリオ暦年→韓国暦年変換]
    F -->|No| H[結果返却]
    G --> H
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | 年オフセット | 韓国暦年 = グレゴリオ暦年 + 2333 | 全ての年変換処理 |
| BR-81-02 | 有効年範囲 | 2334年（西暦1年）〜12332年（西暦9999年） | 年の入力・出力時 |
| BR-81-03 | うるう年判定 | グレゴリオ暦と同一ルール（4で割り切れ、100で割り切れない、400で割り切れる） | IsLeapYear呼び出し時 |
| BR-81-04 | 時代 | KoreanEra（1）のみサポート | Era検証時 |

### 計算ロジック

**グレゴリオ暦年への変換**:
```
GetGregorianYear = Year - YEAR_OFFSET  ' YEAR_OFFSET = 2333
```

**韓国暦年の取得**:
```
GetYear = CorDateTime.GetYear(Time) + YEAR_OFFSET
```

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

本機能はデータベースを直接操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentOutOfRangeException | 範囲外エラー | Year < 2334 または Year > 12332 | 有効な年を指定する |
| ArgumentOutOfRangeException | 範囲外エラー | Month < 1 または Month > 12 | 有効な月を指定する |
| ArgumentOutOfRangeException | 範囲外エラー | Day < 1 または Day > 該当月の日数 | 有効な日を指定する |
| Argument_InvalidEraValue | 無効な時代 | Era が 1 以外 | KoreanEra(1)を指定する |
| InvalidOperationException | 読み取り専用 | ReadOnlyインスタンスへの書き込み | 書き込み可能なインスタンスを使用する |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

特になし（インメモリ計算のみ）

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

特になし

## 備考

- .NET FrameworkのSystem.Globalization.KoreanCalendarと互換性のあるAPI
- ICloneableインターフェースを実装し、Clone()メソッドによるコピーが可能
- PropertyBagによるシリアライズ/デシリアライズに対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | KoreanCalendar.cls | `Source/CorLib/System.Globalization/KoreanCalendar.cls` | 定数定義（MinKoreanYear=2334, MaxKoreanYear=12332, YEAR_OFFSET=2333）とメンバ変数（mTwoDigitYearMax, mIsReadOnly）を確認 |

**読解のコツ**: VB6のクラスモジュールでは、`Private`で宣言された変数がメンバ変数となる。`Const`はクラス定数。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | KoreanCalendar.cls | `Source/CorLib/System.Globalization/KoreanCalendar.cls` | 公開メソッド（AddDays, GetYear, ToDateTime等）の呼び出しパターンを理解 |

**主要処理フロー**:
1. **169-171行目**: AddDays - Statics.Calendar.AddDaysを呼び出し
2. **256-258行目**: GetDayOfMonth - CorDateTime.GetDayOfMonthを呼び出し
3. **414-416行目**: GetYear - CorDateTime.GetYear(Time) + YEAR_OFFSETで韓国暦年を計算
4. **498-506行目**: ToDateTime - ValidateEra/Year/Monthの後、Cor.NewDateTimeでCorDateTimeを生成

#### Step 3: 年変換ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | KoreanCalendar.cls | `Source/CorLib/System.Globalization/KoreanCalendar.cls` | GetGregorianYear関数（620-622行目）とGetYear関数（414-416行目） |

**主要処理フロー**:
- **620-622行目**: グレゴリオ暦年への変換（Year - YEAR_OFFSET）
- **414-416行目**: 韓国暦年の取得（CorDateTime.GetYear + YEAR_OFFSET）

#### Step 4: バリデーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | KoreanCalendar.cls | `Source/CorLib/System.Globalization/KoreanCalendar.cls` | ValidateEra, ValidateYear, ValidateMonthメソッド |

**主要処理フロー**:
- **599-606行目**: ValidateEra - KoreanEra(1)またはCurrentEraのみ許可
- **608-612行目**: ValidateYear - 2334〜12332の範囲チェック
- **614-617行目**: ValidateMonth - 1〜12の範囲チェック

#### Step 5: 静的クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | KoreanCalendarStatic.cls | `Source/CorLib/System.Globalization/KoreanCalendarStatic.cls` | KoreanEraプロパティ（常に1を返す） |

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

```
KoreanCalendar
    │
    ├─ AddDays/AddMonths/AddYears等
    │      └─ Statics.Calendar.AddXxx
    │              └─ CorDateTime演算
    │
    ├─ GetDayOfMonth/GetMonth/GetYear等
    │      └─ CorDateTime.GetXxx
    │              └─ 年の場合: + YEAR_OFFSET
    │
    ├─ ToDateTime
    │      ├─ ValidateEra/Year/Month
    │      ├─ GetGregorianYear (- YEAR_OFFSET)
    │      └─ Cor.NewDateTime
    │
    └─ IsLeapYear/IsLeapDay
           └─ CorDateTime.IsLeapYear (変換後のグレゴリオ暦年で判定)
```

### データフロー図

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

韓国暦年(2334-12332) ──▶ - YEAR_OFFSET ──▶ グレゴリオ暦年(1-9999)
                                │
                                ▼
                         CorDateTime処理
                                │
                                ▼
グレゴリオ暦年(1-9999) ──▶ + YEAR_OFFSET ──▶ 韓国暦年(2334-12332)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| KoreanCalendar.cls | `Source/CorLib/System.Globalization/KoreanCalendar.cls` | ソース | メインクラス（日付計算処理） |
| KoreanCalendarStatic.cls | `Source/CorLib/System.Globalization/KoreanCalendarStatic.cls` | ソース | 静的メソッド（KoreanEra定数） |
| KoreanCalendarTests.cls | `Source/Tests/System.Globalization/KoreanCalendarTests.cls` | テスト | 単体テスト |
| modCalendarHelpers.bas | `Source/CorLib/System.Globalization/modCalendarHelpers.bas` | ソース | カレンダー共通ヘルパー |
| Calendar.cls | `Source/CorLib/System.Globalization/Calendar.cls` | ソース | 基底インターフェース |
