> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# InteractsWithTime trait

> 說明用於 Queue、Cache、Scheduling 的時間計算工具 trait 及其活用方式。

## 什麼是 InteractsWithTime

`Illuminate\Support\InteractsWithTime` 是彙整了時間、延遲、經過時間計算的 trait。在 Laravel 框架內有超過 40 個類別 `use InteractsWithTime;`，於 Cache、Queue、Console、資料庫連線等廣泛的元件中使用。

<Info>
  原始碼位於 `src/Illuminate/Support/InteractsWithTime.php`。僅由 `protected` 方法組成，前提是由類別內部呼叫的用途。
</Info>

## 框架內的使用範例

| 類別                                      | 使用目的            |
| --------------------------------------- | --------------- |
| `Cache\ArrayStore` / `DatabaseStore` 等  | TTL（有效期限）的計算    |
| `Cache\RateLimiter`                     | 速率限制的重置時刻       |
| `Queue\Console\RestartCommand`          | Worker 重啟時間戳記   |
| `Database\Connection`                   | 查詢執行時間的量測       |
| `Console\View\Components\Task`          | 指令 Task 執行時間顯示  |
| `Redis\Limiters\DurationLimiterBuilder` | Redis 速率限制的期間計算 |

## 方法解說

### `secondsUntil()` — 取得剩餘秒數

回傳至指定日期時間或延遲值的剩餘秒數。引數可傳入 `DateTimeInterface`、`DateInterval` 或秒數整數其中之一。

```php theme={null}
use Illuminate\Support\InteractsWithTime;

class MyService
{
    use InteractsWithTime;

    public function scheduleAt(\DateTime $target): int
    {
        return $this->secondsUntil($target); // 從現在到 $target 的秒數
    }
}
```

若傳入過去的日期時間會回傳 `0`（不會為負數）。

```php theme={null}
$seconds = $this->secondsUntil(now()->addMinutes(5)); // 300
$seconds = $this->secondsUntil(now()->subMinutes(5)); // 0（過去為 0）
$seconds = $this->secondsUntil(60);                   // 60（整數直接視為秒數）
```

### `availableAt()` — 可用時的 UNIX 時間戳記

回傳於當前時刻加上延遲後的 UNIX 時間戳記。用於 Queue Job 延遲或 Cache 的有效期限計算。

```php theme={null}
$timestamp = $this->availableAt(60);              // 60 秒後的 UNIX 時間戳記
$timestamp = $this->availableAt(new \DateTime('2026-12-31')); // 指定日期時間的 UNIX 時間戳記
$timestamp = $this->availableAt(new \DateInterval('PT5M'));    // 5 分後
```

若不帶引數（預設 `0`）呼叫，則回傳當前時刻的時間戳記。

### `parseDateInterval()` — 將 DateInterval 轉為 DateTime

若接收 `DateInterval` 實例，會轉換為加至當前時刻的 `Carbon` 實例後回傳。`DateTimeInterface` 或整數值則原樣回傳。

```php theme={null}
$delay = $this->parseDateInterval(new \DateInterval('P1D')); // 明天的 Carbon
$delay = $this->parseDateInterval(now()->addHour());         // DateTimeInterface 原樣回傳
$delay = $this->parseDateInterval(3600);                     // 3600（整數原樣回傳）
```

`secondsUntil()` 與 `availableAt()` 內部都會呼叫此方法。

### `currentTime()` — 當前時刻的 UNIX 時間戳記

回傳 `Carbon::now()->getTimestamp()` 的簡單 wrapper。用作 `secondsUntil()` 的基準時刻。

```php theme={null}
$now = $this->currentTime(); // int（UNIX 時間戳記）
```

### `runTimeForHumans()` — 將執行時間轉為人類易讀的格式

將以 `microtime(true)` 記錄的起始時刻與結束時刻的差，轉換為易讀的字串。

```php theme={null}
$start = microtime(true);

// ... 處理 ...

echo $this->runTimeForHumans($start); // 例：「42.15ms」或「1s 234ms」
```

未達 1000ms 時以如 `42.15ms` 帶小數點的毫秒表示，1000ms 以上則以 CarbonInterval 的 `forHumans()` 短縮形式（如 `1s 234ms`）回傳。

亦可將結束時刻傳入第 2 個引數，以轉換已量測的區間。

```php theme={null}
$elapsed = $this->runTimeForHumans($start, $end);
```

## 套件開發的活用

### Cache Driver 的 TTL 統一

當要建立 `put(key, value, ttl)` 中 `ttl` 可接受 `int`、`DateInterval`、`DateTime` 皆可的方法時很方便。

```php theme={null}
use Illuminate\Support\InteractsWithTime;

class MyStore
{
    use InteractsWithTime;

    public function put(string $key, mixed $value, mixed $ttl): void
    {
        $seconds = $this->secondsUntil($ttl);

        // 以 $seconds（int）儲存至實際儲存位置
        $this->storage[$key] = [
            'value'      => $value,
            'expires_at' => $this->availableAt($ttl),
        ];
    }
}
```

### Console 指令的處理時間顯示

於 `Artisan` 指令的 `handle()` 中向使用者顯示處理時間時可以活用。

```php theme={null}
use Illuminate\Console\Command;
use Illuminate\Support\InteractsWithTime;

class ProcessDataCommand extends Command
{
    use InteractsWithTime;

    public function handle(): void
    {
        $start = microtime(true);

        // ... 處理 ...

        $this->info("完成：{$this->runTimeForHumans($start)}");
    }
}
```

## 測試用的 InteractsWithTime

`Illuminate\Foundation\Testing\Concerns\InteractsWithTime` 為另一物，提供在測試案例中操作時間的 `travel*()` 方法（會自動整合至 `TestCase`）。

```php theme={null}
// 於測試中推進時間（Testing\Concerns\InteractsWithTime）
$this->travel(5)->days();
$this->travelTo(now()->addMonth());
$this->travelBack();
```

與 `Illuminate\Support\InteractsWithTime`（本頁主題）命名空間不同，請留意勿混淆。

## 總結

| 方法                               | 回傳值                      | 主要用途                       |
| -------------------------------- | ------------------------ | -------------------------- |
| `secondsUntil($delay)`           | `int`                    | 取得剩餘秒數                     |
| `availableAt($delay)`            | `int`                    | 計算有效開始時間戳記                 |
| `parseDateInterval($delay)`      | `DateTimeInterface\|int` | 將 DateInterval → Carbon 轉換 |
| `currentTime()`                  | `int`                    | 當前 UNIX 時間戳記               |
| `runTimeForHumans($start, $end)` | `string`                 | 執行時間的易讀表示                  |

若想建立引數可接受 `int`、`DateInterval`、`DateTimeInterface` 任一者的方法，僅需 `use` 此 trait 即可省去重新實作轉換邏輯。

## 相關頁面

* [套件開發](/zh-TW/advanced/package-development)
* [InteractsWithData trait](/zh-TW/advanced/interacts-with-data)
* [Conditionable trait](/zh-TW/advanced/conditionable)


## Related topics

- [InteractsWithData trait](/zh-TW/advanced/interacts-with-data.md)
- [廣播](/zh-TW/broadcasting.md)
- [PHP Attributes](/zh-TW/advanced/php-attributes.md)
- [Fluent 類別](/zh-TW/advanced/fluent.md)
- [进阶主题](/zh-CN/advanced/index.md)
