跳转到主要内容

什么是 InteractsWithTime

Illuminate\Support\InteractsWithTime 是把时间、延迟、耗时计算聚合到一起的 trait。在 Laravel 框架中,有 40 多个类都 use InteractsWithTime;,被广泛用于缓存、队列、Console、数据库连接等组件。
源码位于 src/Illuminate/Support/InteractsWithTime.php。它只由 protected 方法组成,前提是在类内部使用。

框架内的使用示例

用途
Cache\ArrayStore / DatabaseStoreTTL(有效期)的计算
Cache\RateLimiter限流的重置时间
Queue\Console\RestartCommandWorker 重启时间戳
Database\Connection查询执行时间的度量
Console\View\Components\Task命令任务的耗时显示
Redis\Limiters\DurationLimiterBuilderRedis 限流的时段计算

方法解析

secondsUntil() — 获取剩余秒数

返回距指定日期时间或延迟值的剩余秒数。参数可以是 DateTimeInterfaceDateInterval,或秒数的整数。
use Illuminate\Support\InteractsWithTime;

class MyService
{
    use InteractsWithTime;

    public function scheduleAt(\DateTime $target): int
    {
        return $this->secondsUntil($target); // 从当前到 $target 的秒数
    }
}
传入过去的时间会返回 0(不会为负值)。
$seconds = $this->secondsUntil(now()->addMinutes(5)); // 300
$seconds = $this->secondsUntil(now()->subMinutes(5)); // 0(过去为 0)
$seconds = $this->secondsUntil(60);                   // 60(整数直接作为秒数)

availableAt() — 可用时刻的 UNIX 时间戳

返回当前时间加上延迟后的 UNIX 时间戳。可用于队列任务延迟或缓存有效期计算。
$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 或整数会原样返回。
$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() 的简单包装。作为 secondsUntil() 的基准时间。
$now = $this->currentTime(); // int(UNIX 时间戳)

runTimeForHumans() — 将耗时转换为易读形式

microtime(true) 记录的开始时间与结束时间之差转换为易读字符串。
$start = microtime(true);

// ... 处理 ...

echo $this->runTimeForHumans($start); // 例如:"42.15ms" 或 "1s 234ms"
不足 1000ms 时以 42.15ms 的方式返回带小数的毫秒,1000ms 及以上时返回 CarbonInterval 的 forHumans() 简写形式(如 1s 234ms)。 第 2 个参数可传入结束时间,用于转换已经度量过的时间段。
$elapsed = $this->runTimeForHumans($start, $end);

在包开发中的应用

统一缓存驱动的 TTL

在编写 put(key, value, ttl) 之类同时接受 intDateIntervalDateTime 三种 TTL 的方法时特别方便。
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),
        ];
    }
}

控制台命令的耗时显示

可用于在 Artisan 命令的 handle() 中向用户展示处理耗时。
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 是另一个 trait,提供在测试用例中操作时间的 travel*() 方法(会自动集成到 TestCase)。
// 在测试中前进时间(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|intDateInterval → Carbon 转换
currentTime()int当前 UNIX 时间戳
runTimeForHumans($start, $end)string面向人类的耗时展示
想编写既能接受 int、又能接受 DateIntervalDateTimeInterface 的方法时,只需 use 这个 trait,即可复用其转换逻辑。

相关页面

最后修改于 2026年7月13日