You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
5.1 KiB
187 lines
5.1 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* This file is part of the Carbon package.
|
|
*
|
|
* (c) Brian Nesbitt <brian@nesbot.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Carbon;
|
|
|
|
use DateTime;
|
|
use DateTimeImmutable;
|
|
use DateTimeInterface;
|
|
use DateTimeZone;
|
|
use Psr\Clock\ClockInterface as PsrClockInterface;
|
|
use RuntimeException;
|
|
use Symfony\Component\Clock\ClockInterface;
|
|
|
|
final class WrapperClock implements ClockInterface
|
|
{
|
|
public function __construct(
|
|
private PsrClockInterface|Factory|DateTimeInterface $currentClock,
|
|
) {
|
|
}
|
|
|
|
public function unwrap(): PsrClockInterface|Factory|DateTimeInterface
|
|
{
|
|
return $this->currentClock;
|
|
}
|
|
|
|
public function getFactory(): Factory
|
|
{
|
|
if ($this->currentClock instanceof Factory) {
|
|
return $this->currentClock;
|
|
}
|
|
|
|
if ($this->currentClock instanceof DateTime) {
|
|
$factory = new Factory();
|
|
$factory->setTestNowAndTimezone($this->currentClock);
|
|
|
|
return $factory;
|
|
}
|
|
|
|
if ($this->currentClock instanceof DateTimeImmutable) {
|
|
$factory = new FactoryImmutable();
|
|
$factory->setTestNowAndTimezone($this->currentClock);
|
|
|
|
return $factory;
|
|
}
|
|
|
|
$factory = new FactoryImmutable();
|
|
$factory->setTestNowAndTimezone(fn () => $this->currentClock->now());
|
|
|
|
return $factory;
|
|
}
|
|
|
|
private function nowRaw(): DateTimeInterface
|
|
{
|
|
if ($this->currentClock instanceof DateTimeInterface) {
|
|
return $this->currentClock;
|
|
}
|
|
|
|
if ($this->currentClock instanceof Factory) {
|
|
return $this->currentClock->__call('now', []);
|
|
}
|
|
|
|
return $this->currentClock->now();
|
|
}
|
|
|
|
public function now(): DateTimeImmutable
|
|
{
|
|
$now = $this->nowRaw();
|
|
|
|
return $now instanceof DateTimeImmutable
|
|
? $now
|
|
: new CarbonImmutable($now);
|
|
}
|
|
|
|
/**
|
|
* @template T of CarbonInterface
|
|
*
|
|
* @param class-string<T> $class
|
|
*
|
|
* @return T
|
|
*/
|
|
public function nowAs(string $class, DateTimeZone|string|int|null $timezone = null): CarbonInterface
|
|
{
|
|
$now = $this->nowRaw();
|
|
$date = $now instanceof $class ? $now : $class::instance($now);
|
|
|
|
return $timezone === null ? $date : $date->setTimezone($timezone);
|
|
}
|
|
|
|
public function nowAsCarbon(DateTimeZone|string|int|null $timezone = null): CarbonInterface
|
|
{
|
|
$now = $this->nowRaw();
|
|
|
|
return $now instanceof CarbonInterface
|
|
? ($timezone === null ? $now : $now->setTimezone($timezone))
|
|
: $this->dateAsCarbon($now, $timezone);
|
|
}
|
|
|
|
private function dateAsCarbon(DateTimeInterface $date, DateTimeZone|string|int|null $timezone): CarbonInterface
|
|
{
|
|
return $date instanceof DateTimeImmutable
|
|
? new CarbonImmutable($date, $timezone)
|
|
: new Carbon($date, $timezone);
|
|
}
|
|
|
|
public function sleep(float|int $seconds): void
|
|
{
|
|
if ($seconds === 0 || $seconds === 0.0) {
|
|
return;
|
|
}
|
|
|
|
if ($seconds < 0) {
|
|
throw new RuntimeException('Expected positive number of seconds, '.$seconds.' given');
|
|
}
|
|
|
|
if ($this->currentClock instanceof DateTimeInterface) {
|
|
$this->currentClock = $this->addSeconds($this->currentClock, $seconds);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->currentClock instanceof ClockInterface) {
|
|
$this->currentClock->sleep($seconds);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->currentClock = $this->addSeconds($this->currentClock->now(), $seconds);
|
|
}
|
|
|
|
public function withTimeZone(DateTimeZone|string $timezone): static
|
|
{
|
|
if ($this->currentClock instanceof ClockInterface) {
|
|
return new self($this->currentClock->withTimeZone($timezone));
|
|
}
|
|
|
|
$now = $this->currentClock instanceof DateTimeInterface
|
|
? $this->currentClock
|
|
: $this->currentClock->now();
|
|
|
|
if (!($now instanceof DateTimeImmutable)) {
|
|
$now = clone $now;
|
|
}
|
|
|
|
if (\is_string($timezone)) {
|
|
$timezone = new DateTimeZone($timezone);
|
|
}
|
|
|
|
return new self($now->setTimezone($timezone));
|
|
}
|
|
|
|
private function addSeconds(DateTimeInterface $date, float|int $seconds): DateTimeInterface
|
|
{
|
|
$secondsPerHour = CarbonInterface::SECONDS_PER_MINUTE * CarbonInterface::MINUTES_PER_HOUR;
|
|
$hours = number_format(
|
|
floor($seconds / $secondsPerHour),
|
|
thousands_separator: '',
|
|
);
|
|
$microseconds = number_format(
|
|
($seconds - $hours * $secondsPerHour) * CarbonInterface::MICROSECONDS_PER_SECOND,
|
|
thousands_separator: '',
|
|
);
|
|
|
|
if (!($date instanceof DateTimeImmutable)) {
|
|
$date = clone $date;
|
|
}
|
|
|
|
if ($hours !== '0') {
|
|
$date = $date->modify("$hours hours");
|
|
}
|
|
|
|
if ($microseconds !== '0') {
|
|
$date = $date->modify("$microseconds microseconds");
|
|
}
|
|
|
|
return $date;
|
|
}
|
|
}
|
|
|