P粉5305192342023-08-01 09:41:04
我個人更喜歡使用高級物件而不僅僅是數組或字串,所以這是我處理的方式。對有些人來說,這可能有些過度,我完全理解,不過核心方法也可以很容易地重寫為全域函數,希望這一點可以考慮到。
我認為整體上非常簡單明了,幾乎與您的程式碼完全相同,只是在分割後我們將其轉換為整數,然後驗證小時是否在預期範圍內。
readonly class MySqlTime { public function __construct( public int $hours, public int $minutes, public int $seconds, ) { } public static function fromMySqlTimeAsDurationInDay(string $time): self { [$hours, $minutes, $seconds] = array_map('intval', explode(':', $time)); // Ensure only positive values on a single day. // MySql should already be throwing errors about minutes or seconds being out of range, so we don't // need to check those. // The seconds could include decimals, however for this purpose we are ignoring them. if ($hours > 23 || $hours < 0) { throw new InvalidArgumentException('Hours must be between 0 and 23'); } return new self($hours, $minutes, $seconds); } public function toDateTime(DateTimeInterface $dateTime = null) : DateTimeInterface { $dateTime ??= new DateTimeImmutable(); return $dateTime->setTime($this->hours, $this->minutes, $this->seconds); } }
用法:
var_dump(MySqlTime::fromMySqlTimeAsDurationInDay('12:34:56')->toDateTime());
輸出:
object(DateTimeImmutable)#3 (3) { ["date"]=> string(26) "2023-07-31 12:34:56.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(16) "Europe/Amsterdam" }
Demo: https://3v4l.org/B6mr4#v8.2.7