1<?php 2 3/** 4 * This file is part of the Nette Framework (https://nette.org) 5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com) 6 */ 7 8declare(strict_types=1); 9 10namespace Nette\Utils; 11 12use Nette; 13 14 15/** 16 * DateTime. 17 */ 18class DateTime extends \DateTime implements \JsonSerializable 19{ 20 use Nette\SmartObject; 21 22 /** minute in seconds */ 23 public const MINUTE = 60; 24 25 /** hour in seconds */ 26 public const HOUR = 60 * self::MINUTE; 27 28 /** day in seconds */ 29 public const DAY = 24 * self::HOUR; 30 31 /** week in seconds */ 32 public const WEEK = 7 * self::DAY; 33 34 /** average month in seconds */ 35 public const MONTH = 2_629_800; 36 37 /** average year in seconds */ 38 public const YEAR = 31_557_600; 39 40 41 /** 42 * Creates a DateTime object from a string, UNIX timestamp, or other DateTimeInterface object. 43 * @throws \Exception if the date and time are not valid. 44 */ 45 public static function from(string|int|\DateTimeInterface|null $time): static 46 { 47 if ($time instanceof \DateTimeInterface) { 48 return new static($time->format('Y-m-d H:i:s.u'), $time->getTimezone()); 49 50 } elseif (is_numeric($time)) { 51 if ($time <= self::YEAR) { 52 $time += time(); 53 } 54 55 return (new static('@' . $time))->setTimezone(new \DateTimeZone(date_default_timezone_get())); 56 57 } else { // textual or null 58 return new static((string) $time); 59 } 60 } 61 62 63 /** 64 * Creates DateTime object. 65 * @throws Nette\InvalidArgumentException if the date and time are not valid. 66 */ 67 public static function fromParts( 68 int $year, 69 int $month, 70 int $day, 71 int $hour = 0, 72 int $minute = 0, 73 float $second = 0.0, 74 ): static 75 { 76 $s = sprintf('%04d-%02d-%02d %02d:%02d:%02.5F', $year, $month, $day, $hour, $minute, $second); 77 if ( 78 !checkdate($month, $day, $year) 79 || $hour < 0 80 || $hour > 23 81 || $minute < 0 82 || $minute > 59 83 || $second < 0 84 || $second >= 60 85 ) { 86 throw new Nette\InvalidArgumentException("Invalid date '$s'"); 87 } 88 89 return new static($s); 90 } 91 92 93 /** 94 * Returns new DateTime object formatted according to the specified format. 95 */ 96 public static function createFromFormat( 97 string $format, 98 string $time, 99 string|\DateTimeZone|null $timezone = null, 100 ): static|false 101 { 102 if ($timezone === null) { 103 $timezone = new \DateTimeZone(date_default_timezone_get()); 104 105 } elseif (is_string($timezone)) { 106 $timezone = new \DateTimeZone($timezone); 107 } 108 109 $date = parent::createFromFormat($format, $time, $timezone); 110 return $date ? static::from($date) : false; 111 } 112 113 114 /** 115 * Returns JSON representation in ISO 8601 (used by JavaScript). 116 */ 117 public function jsonSerialize(): string 118 { 119 return $this->format('c'); 120 } 121 122 123 /** 124 * Returns the date and time in the format 'Y-m-d H:i:s'. 125 */ 126 public function __toString(): string 127 { 128 return $this->format('Y-m-d H:i:s'); 129 } 130 131 132 /** 133 * Creates a copy with a modified time. 134 */ 135 public function modifyClone(string $modify = ''): static 136 { 137 $dolly = clone $this; 138 return $modify ? $dolly->modify($modify) : $dolly; 139 } 140} 141