Test project for media files management.
<?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;
}
}