# 機能設計書 76-GregorianCalendar

## 概要

本ドキュメントは、VBCorLibライブラリにおけるGregorianCalendarクラスの機能設計を記載する。GregorianCalendarは、グレゴリオ暦（西暦）に基づく日付計算を提供するカレンダークラスである。

### 本機能の処理概要

GregorianCalendarは、世界で最も広く使用されているグレゴリオ暦に基づいた日付操作メソッドを提供するクラスである。Calendarインターフェースを実装し、日付の加算、減算、年月日の取得、閏年判定などの機能を提供する。

**業務上の目的・背景**：グレゴリオ暦は1582年にローマ教皇グレゴリウス13世によって制定された暦法で、現在世界中で標準的に使用されている。ビジネスアプリケーションにおいて日付計算は基本的な機能であり、本クラスは.NET Frameworkとの互換性を持つVB6実装を提供することで、既存資産の移植性を向上させる。

**機能の利用シーン**：一般的な日付計算、期限管理、スケジュール管理、会計期間の計算、年齢計算、期間計算などで利用される。CultureInfoを通じてカルチャ固有のカレンダーとして設定される場合もある。

**主要な処理内容**：
1. 日付への時間単位の加算（AddDays, AddMonths, AddYears, AddHours等）
2. 日付からの情報抽出（GetYear, GetMonth, GetDayOfMonth等）
3. 閏年判定（IsLeapYear, IsLeapMonth, IsLeapDay）
4. 月の日数取得（GetDaysInMonth, GetDaysInYear）
5. 週番号の計算（GetWeekOfYear）
6. 2桁年から4桁年への変換（ToFourDigitYear）

**関連システム・外部連携**：CultureInfoクラスと連携してカルチャのデフォルトカレンダーとして使用される。CorDateTimeクラスと連携して日付計算を実現する。

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

## 関連画面

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

## 機能種別

計算処理（日付演算）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Time | Variant | Yes | 操作対象の日付（DateまたはCorDateTime） | 有効な日付であること |
| Year | Long | Yes (一部) | 年 | 1-9999の範囲 |
| Month | Long | Yes (一部) | 月 | 1-12の範囲 |
| Day | Long | Yes (一部) | 日 | 月に応じた有効な日 |
| Era | Long | No | 紀元 | 1（AD）のみサポート |

### 入力データソース

プログラムから渡される日付値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| AddXxx戻り値 | CorDateTime | 計算後の日付 |
| GetXxx戻り値 | Long | 抽出された日付要素 |
| IsLeapXxx戻り値 | Boolean | 閏年/閏月/閏日かどうか |
| TwoDigitYearMax | Long | 2桁年変換の最大年 |
| Eras | Long() | サポートする紀元配列 |
| AlgorithmType | CalendarAlgorithmType | カレンダー種別（SolarCalendar） |
| MinSupportedDateTime | CorDateTime | サポートする最小日時 |
| MaxSupportedDateTime | CorDateTime | サポートする最大日時 |

### 出力先

メソッドの戻り値として返却される。

## 処理フロー

### 処理シーケンス

```
1. 日付加算処理（AddDays等）
   ├─ 入力日付のバリデーション
   ├─ 指定時間単位の加算
   └─ 新しいCorDateTimeの生成
2. 日付情報抽出（GetYear等）
   ├─ 入力日付のバリデーション
   └─ 指定要素の抽出と返却
3. 閏年判定（IsLeapYear等）
   ├─ 年の範囲チェック
   └─ 閏年ルールによる判定
```

### フローチャート

```mermaid
flowchart TD
    A[日付操作要求] --> B{操作種別}
    B -->|AddXxx| C[日付加算処理]
    B -->|GetXxx| D[要素抽出処理]
    B -->|IsLeapXxx| E[閏年判定処理]
    C --> F[Statics.Calendar.AddXxx呼び出し]
    D --> G[CorDateTime.GetDateParts]
    E --> H{年 mod 4 = 0?}
    H -->|Yes| I{年 mod 100 = 0?}
    H -->|No| J[閏年ではない]
    I -->|Yes| K{年 mod 400 = 0?}
    I -->|No| L[閏年である]
    K -->|Yes| L
    K -->|No| J
    F --> M[新しいCorDateTime返却]
    G --> N[要素値返却]
    L --> O[True返却]
    J --> P[False返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 閏年ルール | 4で割り切れる年は閏年、ただし100で割り切れる年は閏年でない、さらに400で割り切れる年は閏年 | 閏年判定時 |
| BR-02 | 紀元 | AD（1）のみをサポート | Era指定時 |
| BR-03 | 日付範囲 | 0001/01/01から9999/12/31までサポート | 日付操作時 |
| BR-04 | 月の日数 | 1,3,5,7,8,10,12月=31日、4,6,9,11月=30日、2月=28日（閏年は29日） | GetDaysInMonth |
| BR-05 | TwoDigitYearMax | デフォルトは2029、99-9999の範囲で設定可能 | ToFourDigitYear |
| BR-06 | カレンダータイプ | 6種類の言語バージョン（Localized, USEnglish等）をサポート | CalendarType設定時 |

### 計算ロジック

```
閏年判定:
IsLeapYear(Year) = (Year mod 4 = 0) AND ((Year mod 100 <> 0) OR (Year mod 400 = 0))

月の日数:
DaysInMonth = {31, 28/29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

2桁年変換:
If Year < 100 Then
    If Year > TwoDigitYearMax mod 100 Then
        ToFourDigitYear = (TwoDigitYearMax / 100 - 1) * 100 + Year
    Else
        ToFourDigitYear = (TwoDigitYearMax / 100) * 100 + Year
    End If
End If
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentOutOfRange | 引数範囲外 | 年が1-9999の範囲外 | 有効な年を指定 |
| ArgumentOutOfRange | 引数範囲外 | 月が1-12の範囲外 | 有効な月を指定 |
| ArgumentOutOfRange | 引数範囲外 | 日が月の日数を超過 | 有効な日を指定 |
| ArgumentOutOfRange | 引数範囲外 | TwoDigitYearMaxが99-9999の範囲外 | 有効な値を指定 |
| ArgumentOutOfRange | 引数範囲外 | CalendarTypeが無効な列挙値 | 有効な列挙値を指定 |
| InvalidOperation | 無効操作 | ReadOnlyインスタンスへの書き込み | Cloneで変更可能なコピーを作成 |

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

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

## パフォーマンス要件

- 日付計算は軽量な算術演算で実装
- Statics.Calendar経由の共通処理による効率化

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

- ReadOnlyフラグにより、共有インスタンスの意図しない変更を防止

## 備考

- .NET FrameworkのSystem.Globalization.GregorianCalendarクラスと互換性のある実装
- MITライセンスで提供（Copyright (c) 2017 Kelly Ethridge）
- GregorianCalendarTypes列挙型で6種類の言語バージョンを区別

---

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

### 推奨読解順序

#### Step 1: カレンダー構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GregorianCalendar.cls | `Source/CorLib/System.Globalization/GregorianCalendar.cls` | GregorianCalendarTypes列挙型（行70-77） |
| 1-2 | GregorianCalendar.cls | `Source/CorLib/System.Globalization/GregorianCalendar.cls` | メンバ変数（行79-81） |

#### Step 2: 主要メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GregorianCalendar.cls | `Source/CorLib/System.Globalization/GregorianCalendar.cls` | AddDays（行232-234）- Statics.Calendar経由 |
| 2-2 | GregorianCalendar.cls | `Source/CorLib/System.Globalization/GregorianCalendar.cls` | TwoDigitYearMax（行177-200） |

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

```
ユーザーコード / CultureInfo
    │
    ├─ GregorianCalendar.AddDays(Time, Days)
    │      └─ Statics.Calendar.AddDays(Me, Time, Days)
    │
    ├─ GregorianCalendar.GetYear(Time)
    │      └─ CorDateTime.GetDateParts
    │
    ├─ GregorianCalendar.IsLeapYear(Year, Era)
    │      └─ 閏年判定ロジック
    │
    └─ GregorianCalendar.ToFourDigitYear(Year)
           └─ TwoDigitYearMaxに基づく変換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GregorianCalendar.cls | `Source/CorLib/System.Globalization/GregorianCalendar.cls` | ソース | グレゴリオ暦カレンダー |
| GregorianCalendarStatic.cls | `Source/CorLib/System.Globalization/GregorianCalendarStatic.cls` | ソース | 静的メソッド提供 |
| Calendar.cls | `Source/CorLib/System.Globalization/Calendar.cls` | ソース | カレンダー基底インターフェース |
| Statics.cls | `Source/CorLib/Statics.cls` | ソース | 共通カレンダー処理 |
| CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | ソース | 日付時刻クラス |
| CultureInfo.cls | `Source/CorLib/System.Globalization/CultureInfo.cls` | ソース | カルチャ情報 |
