# 機能設計書 172-現在時刻取得

## 概要

本ドキュメントは、libuv の `uv_gettimeofday()` 関数による現在時刻のマイクロ秒精度での取得機能について、その設計仕様を記載する。

### 本機能の処理概要

`uv_gettimeofday()` は、現在時刻をマイクロ秒精度で取得し、`uv_timeval64_t` 構造体に格納して返す関数である。

**業務上の目的・背景**：多くのアプリケーションでは、ファイルのタイムスタンプ付与、ログ記録、イベント発生時刻の記録など、実世界の現在時刻（壁時計時刻）をマイクロ秒精度で取得する必要がある。本機能はクロスプラットフォームで統一されたAPIを通じて、POSIX の `gettimeofday()` 相当の機能を提供する。`uv_clock_gettime()` がナノ秒精度でMONOTONIC/REALTIMEの選択が可能であるのに対し、本関数はマイクロ秒精度のREALTIME時刻に特化したシンプルなAPIである。

**機能の利用シーン**：ログへのタイムスタンプ付与、ファイル作成・更新時刻の記録、イベント発生時刻の追跡、外部システムとのタイムスタンプ共有、パフォーマンス計測（マイクロ秒精度で十分な場合）などに利用される。

**主要な処理内容**：
1. 引数の NULL チェック（tv が NULL の場合 UV_EINVAL を返す）
2. プラットフォーム固有の時刻取得APIの呼び出し
3. 結果を uv_timeval64_t 構造体に格納して返却

**関連システム・外部連携**：Unix 系では POSIX の `gettimeofday()` を使用し、Windows では `GetSystemTimeAsFileTime()` を使用する。

**権限による制御**：特別な権限は不要である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_gettimeofday()によるマイクロ秒精度現在時刻取得のAPI定義 |

## 機能種別

データ取得処理（システム時刻の読み取り専用操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tv | uv_timeval64_t* | Yes | 時刻を格納する構造体へのポインタ | NULL の場合 UV_EINVAL |

### 入力データソース

OSカーネルが管理するシステムクロック（REALTIME: UTC基準の壁時計時刻）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tv->tv_sec | int64_t | エポック（1970年1月1日）からの経過秒数 |
| tv->tv_usec | int32_t | マイクロ秒単位の端数（0-999999） |
| 戻り値 | int | 成功時 0、失敗時は負のエラーコード |

### 出力先

呼び出し元に戻り値として返却。時刻データは引数として渡されたポインタ先の構造体に格納。

## 処理フロー

### 処理シーケンス

```
1. 引数チェック
   └─ tv が NULL なら UV_EINVAL を返す
2. プラットフォーム固有の時刻取得
   └─ Unix: gettimeofday() を呼び出し
   └─ Windows: GetSystemTimeAsFileTime() を呼び出し
3. 結果を構造体に格納
   └─ tv_sec と tv_usec に値をセット
4. 成功時は 0 を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{tv == NULL?}
    B -->|Yes| C[UV_EINVAL を返す]
    B -->|No| D[OS時刻取得API呼び出し]
    D --> E{取得成功?}
    E -->|No| F[エラーコードを返す]
    E -->|Yes| G[tv に値を格納]
    G --> H[0 を返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-172-01 | NULLポインタ検証 | tv が NULL の場合は UV_EINVAL を返す | 常時 |
| BR-172-02 | 壁時計時刻 | 返される時刻はシステム設定のタイムゾーンではなく UTC 基準のエポックからの経過時刻 | 常時 |

### 計算ロジック

Unix 系: `gettimeofday()` の結果を `uv_timeval64_t` にコピーする（tv_sec を int64_t にキャスト、tv_usec を int32_t にキャスト）。
Windows: `GetSystemTimeAsFileTime()` で取得した FILETIME（1601年1月1日からの100ナノ秒刻み）からエポック値（116444736000000000ULL）を減算し、10000000 で割って秒を、剰余を10で割ってマイクロ秒を算出する。

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

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

該当なし（メモリ内操作のみ）。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータエラー | tv が NULL | 有効なポインタを渡す |
| UV__ERR(errno) | システムエラー | Unix で gettimeofday() が失敗 | errno に応じた対処を行う |

### リトライ仕様

リトライは不要。即座に結果が返される同期関数である。

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

該当なし。

## パフォーマンス要件

同期的に完了する軽量な関数であり、通常マイクロ秒オーダーで完了する。

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

特別なセキュリティ要件はない。

## 備考

- `uv_timeval64_t` は tv_sec が int64_t のため2038年問題に対応している。ただし、ソースコード中のコメント（include/uv.h L373）で完全な対応ではないことが注記されている。
- Unix版の実装は `gettimeofday()` を使用しており、Windows版は `GetSystemTimeAsFileTime()` を使用している。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_timeval64_t 構造体の定義（379-382行目）。tv_sec(int64_t) + tv_usec(int32_t) |

**読解のコツ**: `uv_timeval64_t` は POSIX の `struct timeval` を64ビット対応にした構造体で、tv_sec が int64_t、tv_usec が int32_t になっている。マイクロ秒精度である点に注意（ナノ秒の `uv_timespec64_t` とは異なる）。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | API宣言（1890行目）: `int uv_gettimeofday(uv_timeval64_t* tv)` |

**主要処理フロー**:
1. **1890行目**: 関数シグネチャ。tv ポインタのみを受け取るシンプルなAPI

#### Step 3: Unix実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.c | `src/unix/core.c` | Unix版の `uv_gettimeofday()` 実装（1927-1939行目） |

**主要処理フロー**:
- **1930-1931行目**: tv の NULL チェック。NULL なら UV_EINVAL を返す
- **1933-1934行目**: `gettimeofday()` を呼び出し、失敗時は `UV__ERR(errno)` を返す
- **1936-1937行目**: `struct timeval` の値を `uv_timeval64_t` にキャストしてコピー

#### Step 4: Windows実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | util.c | `src/win/util.c` | Windows版の `uv_gettimeofday()` 実装（1728-1743行目） |

**主要処理フロー**:
- **1730行目**: エポック定数の定義（116444736000000000ULL）
- **1734-1735行目**: tv の NULL チェック
- **1737行目**: `GetSystemTimeAsFileTime()` で現在時刻を取得
- **1738-1741行目**: FILETIME を ULARGE_INTEGER に変換し、エポックからの差分を秒とマイクロ秒に変換

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

```
uv_gettimeofday(tv)
    |
    +-- [Unix]
    |   +-- gettimeofday(&time, NULL)
    |
    +-- [Windows]
        +-- GetSystemTimeAsFileTime(&file_time)
        +-- ULARGE_INTEGER 変換
        +-- エポック減算・単位変換
```

### データフロー図

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

(なし) ────▶ uv_gettimeofday() ─────────▶ uv_timeval64_t* tv
                |                              (tv_sec, tv_usec)
                |
                +-- OS時刻取得API
                +-- 単位変換・格納
                                            ──▶ 戻り値 (int)
                                                (0 / エラーコード)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言、uv_timeval64_t の型定義 |
| core.c | `src/unix/core.c` | ソース | Unix版の uv_gettimeofday() 実装 |
| util.c | `src/win/util.c` | ソース | Windows版の uv_gettimeofday() 実装 |
