119 lines
3.8 KiB
PHP
119 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Shared\Helpers;
|
|
|
|
use Carbon\CarbonImmutable;
|
|
use Carbon\CarbonInterface;
|
|
|
|
class DatesHelper
|
|
{
|
|
private const string FRENCH_DATE_REGEX = '/^\d{4}-\d{2}-\d{2}$/';
|
|
|
|
private const string FRENCH_DATE_INVERT_REGEX = '/^\d{2}-\d{2}\d{4}$/';
|
|
|
|
private const string ISO8601_REGEX = '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/';
|
|
|
|
private const string RFC3339_REGEX = '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+\-]\d{2}:\d{2})$/';
|
|
|
|
public function __construct()
|
|
{
|
|
throw new \LogicException('Static class');
|
|
}
|
|
|
|
/**
|
|
* Vérifie si la date actuelle se situe dans l'intervalle donné.
|
|
*/
|
|
public static function isIn(?CarbonInterface $from, ?CarbonInterface $to): bool
|
|
{
|
|
$now = CarbonImmutable::now();
|
|
|
|
return match (true) {
|
|
$from !== null && $to !== null => $now->between($from, $to),
|
|
$from !== null => $now->greaterThanOrEqualTo($from),
|
|
$to !== null => $now->lessThanOrEqualTo($to),
|
|
default => false,
|
|
};
|
|
}
|
|
|
|
public static function toRfc3339(\DateTimeInterface | string $datetime): string
|
|
{
|
|
$datetime = is_string($datetime) ? self::parseDateTime($datetime) : $datetime;
|
|
|
|
return $datetime->format(\DATE_RFC3339);
|
|
}
|
|
|
|
public static function parseDateTime(string $datetime): \DateTimeInterface
|
|
{
|
|
$datetime = trim($datetime);
|
|
|
|
/** @var \DateTimeInterface|null */
|
|
$output = null;
|
|
|
|
switch (true) {
|
|
case (bool) preg_match(self::FRENCH_DATE_REGEX, $datetime):
|
|
$output = self::parseFrench($datetime);
|
|
break;
|
|
case (bool) preg_match(self::FRENCH_DATE_INVERT_REGEX, $datetime):
|
|
$output = self::parseFrenchInverted($datetime);
|
|
break;
|
|
case (bool) preg_match(self::RFC3339_REGEX, $datetime):
|
|
$output = self::parseRfc3339($datetime);
|
|
break;
|
|
case (bool) preg_match(self::ISO8601_REGEX, $datetime):
|
|
$output = self::parseIso8601($datetime);
|
|
break;
|
|
default:
|
|
try {
|
|
$output = new \DateTimeImmutable($datetime);
|
|
} catch (\Exception) {
|
|
throw new \InvalidArgumentException('Unrecognized date/time format: ' . $datetime);
|
|
}
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
protected static function parseFrench(string $datetime): \DateTimeInterface
|
|
{
|
|
$dt = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $datetime . ' 00:00:00');
|
|
|
|
return $dt ?: self::parseFallback($datetime);
|
|
}
|
|
|
|
protected static function parseFrenchInverted(string $datetime): \DateTimeInterface
|
|
{
|
|
$dt = \DateTimeImmutable::createFromFormat('d-m-Y H:i:s', $datetime . ' 00:00:00');
|
|
|
|
return $dt ?: self::parseFallback($datetime);
|
|
}
|
|
|
|
protected static function parseRfc3339(string $datetime): \DateTimeInterface
|
|
{
|
|
$dt = \DateTimeImmutable::createFromFormat(\DateTime::RFC3339, $datetime);
|
|
if ($dt !== false) {
|
|
return $dt;
|
|
}
|
|
|
|
$dt = \DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.uP', $datetime);
|
|
|
|
return $dt ?: self::parseFallback($datetime);
|
|
}
|
|
|
|
protected static function parseIso8601(string $datetime): \DateTimeInterface
|
|
{
|
|
$dt = \DateTimeImmutable::createFromFormat(\DateTimeInterface::ATOM, $datetime);
|
|
|
|
return $dt ?: self::parseFallback($datetime);
|
|
}
|
|
|
|
protected static function parseFallback(string $datetime): \DateTimeInterface
|
|
{
|
|
try {
|
|
return new \DateTimeImmutable($datetime);
|
|
} catch (\Throwable) {
|
|
throw new \InvalidArgumentException("Unrecognized date/time format: {$datetime}");
|
|
}
|
|
}
|
|
}
|