# 機能設計書 3-CorDateTime

## 概要

本ドキュメントは、VBCorLibライブラリにおける日付時刻機能（CorDateTime）の設計を記述する。CorDateTimeクラスは、VB6/VBAの標準Date型を拡張し、.NET Frameworkの`System.DateTime`構造体に相当する高精度な日付時刻操作機能を提供するクラスである。

### 本機能の処理概要

CorDateTimeクラスは、西暦1年1月1日から西暦9999年12月31日までの日付時刻を表現し、ミリ秒精度での演算、タイムゾーン変換、書式設定などの包括的な機能を提供する。

**業務上の目的・背景**：VB6/VBAの標準Date型は西暦100年から9999年までの範囲しかサポートせず、またミリ秒精度の操作やタイムゾーンの概念がない。CorDateTimeは.NET Frameworkと互換性のある日付時刻処理をVB6/VBA環境で実現し、グローバルなビジネスアプリケーション開発において必要となる高精度な時刻管理、タイムゾーン対応、カレンダー対応を可能にする。

**機能の利用シーン**：日付時刻処理を必要とする全ての場面で利用される。具体的には、トランザクションのタイムスタンプ管理、スケジュール管理システム、ログファイルの時刻記録、国際間取引での時刻変換、レポートの日付範囲指定、契約期間の計算などの場面で活用される。

**主要な処理内容**：
1. 日付時刻コンポーネントの取得（Year、Month、Day、Hour、Minute、Second、Millisecond）
2. 日付時刻の加算（Add、AddYears、AddMonths、AddDays、AddHours、AddMinutes、AddSeconds、AddMilliseconds、AddTicks）
3. 日付時刻の減算（Subtract - TimeSpanまたはCorDateTimeを返却）
4. 日付時刻の比較（CompareTo、Equals、GreaterThan、LessThan、EqualTo等）
5. タイムゾーン変換（ToLocalTime、ToUniversalTime）
6. 形式変換（ToOADate、ToFileTime、ToFileTimeUtc、ToBinary）
7. 文字列書式設定（ToString、ToLongDateString、ToShortDateString、ToLongTimeString、ToShortTimeString）
8. 日付部分・時刻部分の抽出（DateOnly、TimeOfDay）

**関連システム・外部連携**：外部システムとの連携はない。内部でTimeZoneクラスと連携してタイムゾーン変換を行う。DateTimeFormatInfoクラスを使用してカルチャ依存の書式設定を実現している。

**権限による制御**：権限による制御は行わない。全てのメソッドは同一の動作を行う。

## 関連画面

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

## 機能種別

計算処理 / データ操作ユーティリティ / 日付時刻処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Year | Long | No | 年（1-9999） | 範囲チェック |
| Month | Long | No | 月（1-12） | 範囲チェック |
| Day | Long | No | 日（1-31） | 月に応じた範囲チェック |
| Hour | Long | No | 時（0-23） | 範囲チェック |
| Minute | Long | No | 分（0-59） | 範囲チェック |
| Second | Long | No | 秒（0-59） | 範囲チェック |
| Millisecond | Long | No | ミリ秒（0-999） | 範囲チェック |
| Value | TimeSpan/CorDateTime/Date | No | 演算対象 | 型チェック |
| Format | String | No | 書式文字列 | 書式パターン |
| Provider | IFormatProvider | No | 書式プロバイダ | CultureInfoまたはDateTimeFormatInfo |
| Kind | DateTimeKind | No | 日付時刻の種類 | 列挙値（Unspecified/Utc/Local） |

### 入力データソース

コンストラクタまたはファクトリメソッド経由で作成されるインスタンス

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 日付コンポーネント | Long | Year、Month、Day等のプロパティ戻り値 |
| 時刻コンポーネント | Long | Hour、Minute、Second、Millisecondプロパティ戻り値 |
| 曜日 | DayOfWeek | DayOfWeekプロパティ戻り値（0=Sunday...6=Saturday） |
| ミリ秒合計 | Currency | TotalMillisecondsプロパティ戻り値 |
| ティック | Variant(Decimal) | Ticksプロパティ戻り値 |
| 演算結果 | CorDateTime | Add系メソッドの戻り値 |
| 差分 | TimeSpan/CorDateTime | Subtractメソッドの戻り値 |
| 比較結果 | Long/Boolean | CompareTo、Equals等の戻り値 |
| OLE日付 | Date | ToOADateの戻り値 |
| ファイル時刻 | Currency | ToFileTime/ToFileTimeUtcの戻り値 |
| 書式化文字列 | String | ToString系メソッドの戻り値 |

### 出力先

呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. インスタンス作成
   └─ ミリ秒値とDateTimeKindを内部変数に保存
2. プロパティ取得（Year、Month、Day等）
   └─ GetDatePartsでミリ秒から日付要素を算出
3. 日付演算（Add系メソッド）
   └─ ミリ秒演算後、新しいCorDateTimeを返却
4. タイムゾーン変換
   └─ TimeZone.CurrentTimeZoneを使用して変換
5. 書式設定
   └─ DateTimeFormatInfoを使用して文字列化
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|プロパティ取得| C[GetDateParts呼び出し]
    B -->|日付演算| D[ミリ秒演算]
    B -->|タイムゾーン変換| E[TimeZone呼び出し]
    B -->|書式設定| F[DateTimeFormatInfo.Format]
    C --> G[日付要素を返却]
    D --> H[新しいCorDateTime生成]
    E --> I[変換済みCorDateTime返却]
    F --> J[書式化文字列返却]
    G --> K[終了]
    H --> K
    I --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 日付範囲 | 1/1/0001 00:00:00.000 ～ 12/31/9999 23:59:59.999 | 全てのメソッド |
| BR-02 | 不変オブジェクト | 演算は常に新しいインスタンスを返す | Add系、Subtract |
| BR-03 | ミリ秒精度 | Currency型で64ビット整数相当の精度 | 内部表現 |
| BR-04 | 曜日の0ベース | DayOfWeekは0=Sunday | DayOfWeekプロパティ |
| BR-05 | 月跨ぎの日調整 | AddMonthsで日が月末を超える場合、月末に調整 | AddMonthsメソッド |

### 計算ロジック

**内部ミリ秒表現**
- Currency型（64ビット固定小数点）を使用
- 小数部は10000分の1ミリ秒（=100ナノ秒=1ティック）
- 西暦1年1月1日 00:00:00.0000からのミリ秒数

**日付要素の算出（GetDateParts）**
```
1. 総日数 = mMilliseconds / MilliSecondsPerDay
2. 400年単位の年数を算出
3. 100年単位の年数を算出
4. 4年単位の年数を算出
5. 1年単位の年数を算出
6. 年内の日から月・日を算出
```

**OLE Automation日付変換**
- 基準日: 1899年12月30日
- 整数部: 基準日からの日数
- 小数部: 時刻（1日=1.0）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | 本機能はデータベース操作を行わない |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentOutOfRangeException | 範囲エラー | ミリ秒値が有効範囲外 | 有効な範囲の値を使用 |
| ArgumentOutOfRangeException | 範囲エラー | AddMonthsの引数が-120000～120000の範囲外 | 有効な範囲を指定 |
| ArgumentNullException | 引数エラー | TimeSpanがNothing | 有効なTimeSpanを渡す |
| OverflowException | オーバーフロー | ToOADateで範囲外の日付 | 有効なOLE日付範囲を使用 |
| ArgumentException | 引数エラー | Subtractで無効な型 | CorDateTime/TimeSpan/Dateを使用 |

### リトライ仕様

リトライは行わない。エラー発生時は即座に例外をスロー。

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

本機能はトランザクション管理を行わない。日付時刻演算はメモリ上で直接実行される。

## パフォーマンス要件

- 日付演算: ミリ秒値の加減算のみで高速処理
- プロパティ取得: GetDatePartsは整数除算のみで効率的に算出
- 不変オブジェクト: 演算ごとに新規オブジェクト生成（スレッドセーフだがメモリ消費あり）

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

- タイムゾーン変換はシステムのタイムゾーン設定に依存
- 外部入力の日付文字列パースは別途検証が必要

## 備考

- Currency型は.NETのInt64に相当する精度を持つ
- VB6のDate型との相互変換が可能（ToOADate、FromOADate）
- IObject、IComparable、IFormattableインターフェースを実装
- 永続化可能（Persistable = 1）

---

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

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

### 推奨読解順序

#### Step 1: 定数と内部変数を理解する

日付計算に使用される定数と内部表現を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 54-65行目: 定数定義（日数計算の基準値） |
| 1-2 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 71-72行目: 内部変数（mMilliseconds、mKind） |

**読解のコツ**: Currency型が64ビット整数として機能し、小数部が10000ティック（=1ミリ秒）を表す点に注目。

#### Step 2: プロパティ実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 81-83行目: Kind - DateTimeKindを返す |
| 2-2 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 133-135行目: Year - GetDatePartsで算出 |
| 2-3 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 142-144行目: Day - GetDatePartsで算出 |
| 2-4 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 151-153行目: Month - GetDatePartsで算出 |
| 2-5 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 173-175行目: DayOfWeek - ミリ秒から直接算出 |
| 2-6 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 182-202行目: Hour/Minute/Second - ミリ秒から直接算出 |

**主要処理フロー**:
1. **134行目**: GetDatePartsでYearPartを指定して年を取得
2. **174行目**: DayOfWeekは総日数を7で割った余りで算出

#### Step 3: 演算メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 264-269行目: Add - TimeSpanを加算 |
| 3-2 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 277-288行目: AddMilliseconds - 基本演算 |
| 3-3 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 329-366行目: AddMonths - 月加算の複雑なロジック |
| 3-4 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 597-619行目: Subtract - 減算（型による分岐） |

**主要処理フロー**:
- **287行目**: AddMillisecondsは新しいCorDateTimeを生成して返す
- **346-357行目**: AddMonthsは年月の繰り上げ/繰り下げを処理
- **361-363行目**: AddMonthsは月末日の調整を行う

#### Step 4: タイムゾーン変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 467-473行目: ToLocalTime - ローカル時間への変換 |
| 4-2 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 480-486行目: ToUniversalTime - UTC時間への変換 |
| 4-3 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 435-437行目: ToFileTime - ファイル時間への変換 |

**主要処理フロー**:
- **468-472行目**: LocalKindの場合はそのまま返す、それ以外はTimeZone.ToLocalTime呼び出し

#### Step 5: 書式設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 514-519行目: ToString - メイン書式設定 |
| 5-2 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 526-537行目: ToLongDateString/ToShortDateString |

#### Step 6: 内部処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 720-728行目: Init - コンストラクタ |
| 6-2 | CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | 791-800行目以降: GetDateParts - 日付要素算出 |

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

```
CorDateTime (Instance)
    │
    ├─ Properties (Year, Month, Day, etc.)
    │      └─ GetDateParts
    │             └─ ミリ秒 → 日付要素の分解
    │
    ├─ Add / AddMilliseconds / AddDays / etc.
    │      └─ CorDateTime.FromMilliseconds
    │             └─ 新しいCorDateTimeインスタンス生成
    │
    ├─ AddMonths
    │      ├─ GetDateParts (年月日取得)
    │      ├─ CorMath.DivRem (年月計算)
    │      ├─ CorDateTime.DaysInMonth (月末日取得)
    │      └─ CorDateTime.FromMilliseconds
    │
    ├─ Subtract
    │      ├─ (TimeSpan) → CorDateTime.FromMilliseconds
    │      └─ (CorDateTime/Date) → TimeSpan.FromMilliseconds
    │
    ├─ ToLocalTime / ToUniversalTime
    │      └─ TimeZone.CurrentTimeZone
    │             ├─ ToLocalTime
    │             └─ ToUniversalTime
    │
    ├─ ToString / ToLong/Short Date/Time String
    │      └─ DateTimeFormatInfo.Format
    │             └─ カルチャ依存の書式設定
    │
    └─ CompareTo / Equals / GreaterThan / etc.
           └─ TotalMilliseconds比較
```

### データフロー図

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

年月日時分秒ミリ秒 ──────▶ Init ─────────────────────────▶ CorDateTime
                              │
                              ▼
                       mMilliseconds (Currency)
                              │
プロパティ要求 ───────────▶ GetDateParts ──────────────────▶ 年/月/日等
                              │
TimeSpan/数値 ────────────▶ Add系メソッド ─────────────────▶ 新CorDateTime
                              │
CorDateTime/TimeSpan ─────▶ Subtract ──────────────────────▶ TimeSpan/CorDateTime
                              │
書式文字列 ───────────────▶ ToString ──────────────────────▶ 書式化文字列
                              │   └─ DateTimeFormatInfo
                              │
タイムゾーン変換要求 ─────▶ ToLocalTime/ToUniversalTime ──▶ 変換済みCorDateTime
                                  └─ TimeZone.CurrentTimeZone
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | ソース | 日付時刻のメインクラス |
| CorDateTimeStatic.cls | `Source/CorLib/System/CorDateTimeStatic.cls` | ソース | 日付時刻の静的メソッド |
| TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | ソース | 時間間隔を表すクラス |
| TimeZone.cls | `Source/CorLib/System/TimeZone.cls` | ソース | タイムゾーン情報 |
| DateTimeFormatInfo.cls | `Source/CorLib/System.Globalization/DateTimeFormatInfo.cls` | ソース | 日付書式情報 |
| Calendar.cls | `Source/CorLib/System.Globalization/Calendar.cls` | ソース | カレンダー基底クラス |
| modDateTime.bas | `Source/CorLib/System/modDateTime.bas` | ソース | 日付時刻ヘルパー関数 |
