mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2025-01-08 17:02:41 +00:00
1271a0c8c0
This method provides generalized, consistent type casting more versatile than PHP's basic type juggling while hiding the significant complexity in achieving this. While this commit does not change any existing code to use the new method, the intent is for both API handlers and database drivers to use the same basic rules for type conversion while still allowing for differing failure modes.
92 lines
4.1 KiB
PHP
92 lines
4.1 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace JKingWeb\Arsse\Misc;
|
|
|
|
class Date {
|
|
const FORMAT = [ // in out
|
|
'iso8601' => ["!Y-m-d\TH:i:s", "Y-m-d\TH:i:s\Z" ], // NOTE: ISO 8601 dates require special input processing because of varying formats for timezone offsets
|
|
'iso8601m' => ["!Y-m-d\TH:i:s.u", "Y-m-d\TH:i:s.u\Z" ], // NOTE: ISO 8601 dates require special input processing because of varying formats for timezone offsets
|
|
'microtime' => ["U.u", "0.u00 U" ], // NOTE: the actual input format at the user level matches the output format; pre-processing is required for PHP not to fail
|
|
'http' => ["!D, d M Y H:i:s \G\M\T", "D, d M Y H:i:s \G\M\T"],
|
|
'sql' => ["!Y-m-d H:i:s", "Y-m-d H:i:s" ],
|
|
'date' => ["!Y-m-d", "Y-m-d" ],
|
|
'time' => ["!H:i:s", "H:i:s" ],
|
|
'unix' => ["U", "U" ],
|
|
'float' => ["U.u", "U.u" ],
|
|
];
|
|
|
|
public static function transform($date, string $outFormat = null, string $inFormat = null, bool $inLocal = false) {
|
|
$date = self::normalize($date, $inFormat, $inLocal);
|
|
if (is_null($date) || is_null($outFormat)) {
|
|
return $date;
|
|
}
|
|
$outFormat = strtolower($outFormat);
|
|
if ($outFormat=="unix") {
|
|
return $date->getTimestamp();
|
|
}
|
|
switch ($outFormat) {
|
|
case 'http': $f = "D, d M Y H:i:s \G\M\T"; break;
|
|
case 'iso8601': $f = "Y-m-d\TH:i:s"; break;
|
|
case 'sql': $f = "Y-m-d H:i:s"; break;
|
|
case 'date': $f = "Y-m-d"; break;
|
|
case 'time': $f = "H:i:s"; break;
|
|
default: $f = $outFormat; break;
|
|
}
|
|
return $date->format($f);
|
|
}
|
|
|
|
public static function normalize($date, string $inFormat = null, bool $inLocal = false) {
|
|
if ($date instanceof \DateTimeInterface) {
|
|
return $date;
|
|
} elseif (is_numeric($date)) {
|
|
$time = (int) $date;
|
|
} elseif ($date===null) {
|
|
return null;
|
|
} elseif (is_string($date)) {
|
|
try {
|
|
$tz = (!$inLocal) ? new \DateTimeZone("UTC") : null;
|
|
if (!is_null($inFormat)) {
|
|
switch ($inFormat) {
|
|
case 'http': $f = "D, d M Y H:i:s \G\M\T"; break;
|
|
case 'iso8601': $f = "Y-m-d\TH:i:sP"; break;
|
|
case 'sql': $f = "Y-m-d H:i:s"; break;
|
|
case 'date': $f = "Y-m-d"; break;
|
|
case 'time': $f = "H:i:s"; break;
|
|
default: $f = $inFormat; break;
|
|
}
|
|
return \DateTime::createFromFormat("!".$f, $date, $tz);
|
|
} else {
|
|
return new \DateTime($date, $tz);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
return null;
|
|
}
|
|
} elseif (is_bool($date)) {
|
|
return null;
|
|
} else {
|
|
$time = (int) $date;
|
|
}
|
|
$tz = (!$inLocal) ? new \DateTimeZone("UTC") : null;
|
|
$d = new \DateTime("now", $tz);
|
|
$d->setTimestamp($time);
|
|
return $d;
|
|
}
|
|
|
|
public static function add(string $interval, $date = null): \DateTimeInterface {
|
|
return self::modify("add", $interval, $date);
|
|
}
|
|
|
|
public static function sub(string $interval, $date = null): \DateTimeInterface {
|
|
return self::modify("sub", $interval, $date);
|
|
}
|
|
|
|
protected static function modify(string $func, string $interval, $date = null): \DateTimeInterface {
|
|
$date = self::normalize($date ?? time());
|
|
if ($date instanceof \DateTimeImmutable) {
|
|
return $date->$func(new \DateInterval($interval));
|
|
} else {
|
|
$date->$func(new \DateInterval($interval));
|
|
return $date;
|
|
}
|
|
}
|
|
}
|