# 機能設計書 4-TimeSpan

## 概要

本ドキュメントは、VBCorLibライブラリにおける時間間隔機能（TimeSpan）の設計を記述する。TimeSpanクラスは、.NET Frameworkの`System.TimeSpan`構造体に相当する時間間隔表現を提供するクラスであり、日・時・分・秒・ミリ秒・ティック単位での時間間隔の表現と演算を可能にする。

### 本機能の処理概要

TimeSpanクラスは、時間の長さ（期間）を表現し、時間間隔の加算・減算、比較、書式設定などの機能を提供する。

**業務上の目的・背景**：VB6/VBAには時間間隔を表す専用の型がなく、日付間の差分を扱う際に不便である。TimeSpanは.NET Frameworkと互換性のある時間間隔処理をVB6/VBA環境で実現し、経過時間の計測、タイムアウト設定、スケジュール間隔の計算など、ビジネスアプリケーションで必要となる時間間隔処理を標準化された方法で行えるようにする。

**機能の利用シーン**：時間間隔の計算を必要とする全ての場面で利用される。具体的には、処理時間の計測、タイムアウト値の設定、スケジュール間隔の定義、日付間の差分計算、稼働時間の集計、レスポンスタイムの分析などの場面で活用される。

**主要な処理内容**：
1. 時間コンポーネントの取得（Days、Hours、Minutes、Seconds、Milliseconds）
2. 合計時間の取得（TotalDays、TotalHours、TotalMinutes、TotalSeconds、TotalMilliseconds、Ticks）
3. 時間間隔の演算（Add、Subtract）
4. 絶対値の取得（Duration）
5. 符号反転（Negate）
6. 比較（CompareTo、Equals）
7. 文字列書式設定（ToString）
8. ハッシュコード生成（GetHashCode）

**関連システム・外部連携**：外部システムとの連携はない。CorDateTimeクラスと連携して日付時刻演算に使用される。TimeSpanStaticクラスを通じてファクトリメソッドや静的比較メソッドを提供。

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

## 関連画面

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

## 機能種別

計算処理 / データ操作ユーティリティ / 時間間隔処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Days | Long | No | 日数 | なし |
| Hours | Long | No | 時間数 | なし |
| Minutes | Long | No | 分数 | なし |
| Seconds | Long | No | 秒数 | なし |
| Milliseconds | Long | No | ミリ秒数 | なし |
| ts | TimeSpan | No | 演算対象のTimeSpan | Nothing許可 |
| Value | TimeSpan | No | 比較対象のTimeSpan | Nothing許可 |
| Format | String | No | 書式文字列 | 標準/カスタム書式 |
| FormatProvider | IFormatProvider | No | 書式プロバイダ | CultureInfo等 |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 時間コンポーネント | Long | Days、Hours、Minutes、Seconds、Millisecondsプロパティ戻り値 |
| 合計時間（Double） | Double | TotalDays、TotalHours、TotalMinutes、TotalSecondsプロパティ戻り値 |
| 合計ミリ秒 | Currency | TotalMillisecondsプロパティ戻り値 |
| ティック | Variant(Decimal) | Ticksプロパティ戻り値 |
| 演算結果 | TimeSpan | Add、Subtract、Duration、Negateメソッドの戻り値 |
| 比較結果 | Long/Boolean | CompareTo、Equalsの戻り値 |
| 書式化文字列 | String | ToStringメソッドの戻り値 |
| ハッシュコード | Long | GetHashCodeの戻り値 |

### 出力先

呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. インスタンス作成
   └─ ミリ秒値を内部変数に保存
2. プロパティ取得（Days、Hours等）
   └─ ミリ秒から各要素を算出（除算と剰余）
3. 時間演算（Add、Subtract）
   └─ TimeSpanStaticの静的メソッドに委譲
4. 書式設定
   └─ TimeSpan.ToStringに委譲
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|プロパティ取得| C[ミリ秒から算出]
    B -->|Total系プロパティ| D[ミリ秒を単位で除算]
    B -->|演算| E[TimeSpanStaticに委譲]
    B -->|書式設定| F[TimeSpan.ToStringに委譲]
    C --> G[値を返却]
    D --> G
    E --> H[新しいTimeSpan返却]
    F --> I[書式化文字列返却]
    G --> J[終了]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ミリ秒精度 | Currency型で64ビット整数相当の精度（ティック対応） | 内部表現 |
| BR-02 | 不変オブジェクト | 演算は常に新しいインスタンスを返す | Add、Subtract、Duration、Negate |
| BR-03 | 負の値対応 | 負の時間間隔を表現可能 | 全てのプロパティ・メソッド |
| BR-04 | 部分値と合計値の区別 | Days等は部分、TotalDays等は合計 | プロパティ |

### 計算ロジック

**内部ミリ秒表現**
- Currency型（64ビット固定小数点）を使用
- 小数部は10000分の1ミリ秒（=100ナノ秒=1ティック）
- 負の値で過去方向の時間間隔を表現

**時間コンポーネントの算出**
```
Days = Fix(mMilliseconds / MilliSecondsPerDay)
Hours = Fix(mMilliseconds / MillisecondsPerHour) Mod 24
Minutes = Fix(mMilliseconds / MillisecondsPerMinute) Mod 60
Seconds = Fix(mMilliseconds / MillisecondsPerSecond) Mod 60
Milliseconds = AsLong(mMilliseconds * MillisecondsPerTick) Mod 1000
```

**合計時間の算出**
```
TotalDays = mMilliseconds / MilliSecondsPerDay
TotalHours = mMilliseconds / MillisecondsPerHour
TotalMinutes = mMilliseconds / MillisecondsPerMinute
TotalSeconds = mMilliseconds / MillisecondsPerSecond
TotalMilliseconds = mMilliseconds
```

**表示形式**
- 標準形式: `[-][d.]hh:mm:ss[.ff]`
- 負の値の場合は先頭にマイナス記号
- 日数がある場合のみ日数部分を表示
- 小数部がある場合のみ小数部を表示

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentException | 引数エラー | IComparable.CompareToでTimeSpan以外が渡された | TimeSpanを渡す |

### リトライ仕様

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

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

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

## パフォーマンス要件

- プロパティ取得: 整数除算と剰余のみで高速処理
- 演算: ミリ秒値の加減算のみで高速処理
- 不変オブジェクト: 演算ごとに新規オブジェクト生成

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

- 特にセキュリティ上の考慮事項はない
- 演算オーバーフローは呼び出し元の責任

## 備考

- Currency型は.NETのInt64に相当する精度を持つ
- IObject、IComparable、IFormattableインターフェースを実装
- 永続化可能（Persistable = 1）
- CorDateTimeのTimeOfDayプロパティや日付演算で使用される

---

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

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

### 推奨読解順序

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

時間計算の基盤となる内部表現を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 56-59行目: 定数と内部変数（mMilliseconds） |

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 98-100行目: TotalMilliseconds - 内部値をそのまま返す |
| 2-2 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 108-110行目: TotalSeconds - ミリ秒を秒に変換 |
| 2-3 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 118-138行目: TotalMinutes/TotalHours/TotalDays |
| 2-4 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 146-148行目: Milliseconds - 部分値（Mod 1000） |
| 2-5 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 156-188行目: Seconds/Minutes/Hours/Days |
| 2-6 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 195-197行目: Ticks - Decimalで返す |

**主要処理フロー**:
1. **99行目**: TotalMillisecondsは内部値mMillisecondsをそのまま返す
2. **147行目**: Millisecondsは`Mod 1000`で部分値を取得
3. **157行目**: Secondsは`Mod 60`で部分値を取得
4. **196行目**: TicksはDecimal変換してTicksPerMillisecond（10000）を乗算

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 67-69行目: Add - TimeSpan.Addに委譲 |
| 3-2 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 76-78行目: Subtract - TimeSpan.Subtractに委譲 |
| 3-3 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 84-90行目: Duration - 絶対値を返す |
| 3-4 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 219-221行目: Negate - 符号反転 |

**主要処理フロー**:
- **68行目**: AddはTimeSpanStatic.Addを呼び出す
- **85-89行目**: Durationは負の場合のみ新しいインスタンスを生成

#### Step 4: 比較・等価性メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 211-213行目: CompareTo - TimeSpan.Compareに委譲 |
| 4-2 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 240-242行目: Equals - TimeSpan.Equalsに委譲 |
| 4-3 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 248-252行目: GetHashCode - XORベースのハッシュ |

#### Step 5: コンストラクタと永続化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 258-260行目: Init - 日時分秒ミリ秒からミリ秒を計算 |
| 5-2 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 262-264行目: InitFromMilliseconds - 直接設定 |
| 5-3 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 270-276行目: シリアライズ処理 |

#### Step 6: インターフェース実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 282-284行目: IFormattable_ToString |
| 6-2 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 290-306行目: IObject実装 |
| 6-3 | TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | 312-322行目: IComparable_CompareTo |

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

```
TimeSpan (Instance)
    │
    ├─ Properties (Days, Hours, Minutes, etc.)
    │      └─ ミリ秒 → 各要素の算出（除算・剰余）
    │
    ├─ Total Properties (TotalDays, TotalHours, etc.)
    │      └─ ミリ秒 → 単位での除算
    │
    ├─ Add
    │      └─ TimeSpan.Add (TimeSpanStatic)
    │             └─ 新しいTimeSpanインスタンス生成
    │
    ├─ Subtract
    │      └─ TimeSpan.Subtract (TimeSpanStatic)
    │             └─ 新しいTimeSpanインスタンス生成
    │
    ├─ Duration
    │      └─ TimeSpan.FromMilliseconds (負の場合)
    │
    ├─ Negate
    │      └─ TimeSpan.FromMilliseconds (-mMilliseconds)
    │
    ├─ CompareTo
    │      └─ TimeSpan.Compare (TimeSpanStatic)
    │
    ├─ Equals
    │      └─ TimeSpan.Equals (TimeSpanStatic)
    │
    └─ ToString
           └─ TimeSpan.ToString (TimeSpanStatic)
                  └─ 書式設定処理
```

### データフロー図

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

日時分秒ミリ秒 ──────────▶ Init ─────────────────────────▶ TimeSpan
                              │
                              ▼
                       mMilliseconds (Currency)
                              │
部分値要求 ────────────────▶ 除算・剰余 ───────────────────▶ Days/Hours等
                              │
合計値要求 ────────────────▶ 除算 ──────────────────────────▶ TotalDays等
                              │
TimeSpan演算 ──────────────▶ TimeSpanStatic ────────────────▶ 新TimeSpan
                              │
書式設定要求 ──────────────▶ TimeSpan.ToString ─────────────▶ 書式化文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | ソース | 時間間隔のメインクラス |
| TimeSpanStatic.cls | `Source/CorLib/System/TimeSpanStatic.cls` | ソース | 時間間隔の静的メソッド |
| CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | ソース | 日付時刻クラス（TimeSpanを使用） |
| modTimeSpan.bas | `Source/CorLib/System/modTimeSpan.bas` | ソース | 時間間隔ヘルパー関数 |
