1<?php 2 3 4namespace ComboStrap; 5 6 7use DateTime; 8 9 10/** 11 * Class Is8601Date 12 * @package ComboStrap 13 * Format used by Google, Sqlite and others 14 * 15 * This is the date class of Combostrap 16 * that takes a valid input string 17 * and output an iso string 18 */ 19class Iso8601Date 20{ 21 public const CANONICAL = "date"; 22 /** 23 * @var DateTime|false 24 */ 25 private $dateTime; 26 27 /** 28 * ATOM = IS08601 29 * See {@link Iso8601Date::getFormat()} for more information 30 */ 31 private const VALID_FORMATS = [ 32 \DateTimeInterface::ATOM, 33 'Y-m-d H:i:sP', 34 'Y-m-d H:i:s', 35 'Y-m-d H:i', 36 'Y-m-d H', 37 'Y-m-d', 38 ]; 39 40 41 /** 42 * Date constructor. 43 */ 44 public function __construct($dateTime = null) 45 { 46 47 if ($dateTime == null) { 48 49 $this->dateTime = new DateTime(); 50 51 } else { 52 53 $this->dateTime = $dateTime; 54 55 } 56 57 } 58 59 /** 60 * @param null $dateString 61 * @return Iso8601Date 62 * @throws ExceptionCombo if the format is not supported 63 */ 64 public static function createFromString($dateString = null): Iso8601Date 65 { 66 67 $original = $dateString; 68 69 if ($dateString === null) { 70 return new Iso8601Date(); 71 } 72 73 /** 74 * Time ? 75 * (ie only YYYY-MM-DD) 76 */ 77 if (strlen($dateString) <= 10) { 78 /** 79 * We had the time to 00:00:00 80 * because {@link DateTime::createFromFormat} with a format of 81 * Y-m-d will be using the actual time otherwise 82 * 83 */ 84 $dateString .= "T00:00:00"; 85 } 86 87 /** 88 * Space as T 89 */ 90 $dateString = str_replace(" ", "T", $dateString); 91 92 93 if (strlen($dateString) <= 13) { 94 /** 95 * We had the time to 00:00:00 96 * because {@link DateTime::createFromFormat} with a format of 97 * Y-m-d will be using the actual time otherwise 98 * 99 */ 100 $dateString .= ":00:00"; 101 } 102 103 if (strlen($dateString) <= 16) { 104 /** 105 * We had the time to 00:00:00 106 * because {@link DateTime::createFromFormat} with a format of 107 * Y-m-d will be using the actual time otherwise 108 * 109 */ 110 $dateString .= ":00"; 111 } 112 113 /** 114 * Timezone 115 */ 116 if (strlen($dateString) <= 19) { 117 /** 118 * Because this text metadata may be used in other part of the application 119 * We add the timezone to make it whole 120 * And to have a consistent value 121 */ 122 $dateString .= date('P'); 123 } 124 125 126 $dateTime = DateTime::createFromFormat(self::getFormat(), $dateString); 127 if ($dateTime === false) { 128 $message = "The date string ($original) is not in a valid date format. (" . join(", ", self::VALID_FORMATS) . ")"; 129 throw new ExceptionCombo($message, self::CANONICAL); 130 } 131 return new Iso8601Date($dateTime); 132 133 } 134 135 public static function createFromTimestamp($timestamp): Iso8601Date 136 { 137 $dateTime = new DateTime(); 138 $dateTime->setTimestamp($timestamp); 139 return new Iso8601Date($dateTime); 140 } 141 142 /** 143 * And note {@link DATE_ISO8601} 144 * because it's not the compliant IS0-8601 format 145 * as explained here 146 * https://www.php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601 147 * ATOM is 148 * 149 * This format is used by Sqlite, Google and is pretty the standard everywhere 150 * https://www.w3.org/TR/NOTE-datetime 151 */ 152 public static function getFormat(): string 153 { 154 return DATE_ATOM; 155 } 156 157 public static function isValid($value): bool 158 { 159 $dateObject = Iso8601Date::createFromString($value); 160 return $dateObject->isValidDateEntry(); 161 } 162 163 public function isValidDateEntry(): bool 164 { 165 if ($this->dateTime !== false) { 166 return true; 167 } else { 168 return false; 169 } 170 } 171 172 public static function createFromDateTime(DateTime $dateTime): Iso8601Date 173 { 174 return new Iso8601Date($dateTime); 175 } 176 177 public static function createFromNow(): Iso8601Date 178 { 179 return new Iso8601Date(); 180 } 181 182 public function getDateTime() 183 { 184 return $this->dateTime; 185 } 186 187 public function __toString() 188 { 189 return $this->getDateTime()->format(self::getFormat()); 190 } 191 192 /** 193 * Shortcut to {@link DateTime::format()} 194 * @param $string 195 * @return string 196 * @link https://php.net/manual/en/datetime.format.php 197 */ 198 public function format($string): string 199 { 200 return $this->getDateTime()->format($string); 201 } 202 203 public function toString() 204 { 205 return $this->__toString(); 206 } 207 208 209 210 211} 212