137748cd8SNickeau<?php 237748cd8SNickeau 337748cd8SNickeau 437748cd8SNickeaunamespace ComboStrap; 537748cd8SNickeau 637748cd8SNickeau 737748cd8SNickeauuse DateTime; 837748cd8SNickeau 937748cd8SNickeau 1037748cd8SNickeau/** 1137748cd8SNickeau * Class Is8601Date 1237748cd8SNickeau * @package ComboStrap 1337748cd8SNickeau * Format used by Google, Sqlite and others 141fa8c418SNickeau * 151fa8c418SNickeau * This is the date class of Combostrap 161fa8c418SNickeau * that takes a valid input string 171fa8c418SNickeau * and output an iso string 1837748cd8SNickeau */ 1937748cd8SNickeauclass Iso8601Date 2037748cd8SNickeau{ 211fa8c418SNickeau public const CANONICAL = "date"; 2237748cd8SNickeau /** 2337748cd8SNickeau * @var DateTime|false 2437748cd8SNickeau */ 2537748cd8SNickeau private $dateTime; 2637748cd8SNickeau 271fa8c418SNickeau /** 281fa8c418SNickeau * ATOM = IS08601 291fa8c418SNickeau * See {@link Iso8601Date::getFormat()} for more information 301fa8c418SNickeau */ 311fa8c418SNickeau private const VALID_FORMATS = [ 321fa8c418SNickeau \DateTimeInterface::ATOM, 331fa8c418SNickeau 'Y-m-d H:i:sP', 341fa8c418SNickeau 'Y-m-d H:i:s', 351fa8c418SNickeau 'Y-m-d H:i', 361fa8c418SNickeau 'Y-m-d H', 371fa8c418SNickeau 'Y-m-d', 381fa8c418SNickeau ]; 391fa8c418SNickeau 4037748cd8SNickeau 4137748cd8SNickeau /** 4237748cd8SNickeau * Date constructor. 4337748cd8SNickeau */ 4437748cd8SNickeau public function __construct($dateTime = null) 4537748cd8SNickeau { 4637748cd8SNickeau 4737748cd8SNickeau if ($dateTime == null) { 4837748cd8SNickeau 4937748cd8SNickeau $this->dateTime = new DateTime(); 5037748cd8SNickeau 5137748cd8SNickeau } else { 5237748cd8SNickeau 5337748cd8SNickeau $this->dateTime = $dateTime; 5437748cd8SNickeau 5537748cd8SNickeau } 5637748cd8SNickeau 5737748cd8SNickeau } 5837748cd8SNickeau 591fa8c418SNickeau public static function create($dateString = null): Iso8601Date 6037748cd8SNickeau { 611fa8c418SNickeau 621fa8c418SNickeau $original = $dateString; 631fa8c418SNickeau 641fa8c418SNickeau if ($dateString === null) { 6537748cd8SNickeau return new Iso8601Date(); 6637748cd8SNickeau } 6737748cd8SNickeau 6837748cd8SNickeau /** 6937748cd8SNickeau * Time ? 7037748cd8SNickeau * (ie only YYYY-MM-DD) 7137748cd8SNickeau */ 721fa8c418SNickeau if (strlen($dateString) <= 10) { 7337748cd8SNickeau /** 7437748cd8SNickeau * We had the time to 00:00:00 7537748cd8SNickeau * because {@link DateTime::createFromFormat} with a format of 7637748cd8SNickeau * Y-m-d will be using the actual time otherwise 7737748cd8SNickeau * 7837748cd8SNickeau */ 791fa8c418SNickeau $dateString .= "T00:00:00"; 801fa8c418SNickeau } 811fa8c418SNickeau 821fa8c418SNickeau /** 831fa8c418SNickeau * Space as T 841fa8c418SNickeau */ 851fa8c418SNickeau $dateString = str_replace(" ", "T", $dateString); 861fa8c418SNickeau 871fa8c418SNickeau 881fa8c418SNickeau if (strlen($dateString) <= 13) { 891fa8c418SNickeau /** 901fa8c418SNickeau * We had the time to 00:00:00 911fa8c418SNickeau * because {@link DateTime::createFromFormat} with a format of 921fa8c418SNickeau * Y-m-d will be using the actual time otherwise 931fa8c418SNickeau * 941fa8c418SNickeau */ 951fa8c418SNickeau $dateString .= ":00:00"; 961fa8c418SNickeau } 971fa8c418SNickeau 981fa8c418SNickeau if (strlen($dateString) <= 16) { 991fa8c418SNickeau /** 1001fa8c418SNickeau * We had the time to 00:00:00 1011fa8c418SNickeau * because {@link DateTime::createFromFormat} with a format of 1021fa8c418SNickeau * Y-m-d will be using the actual time otherwise 1031fa8c418SNickeau * 1041fa8c418SNickeau */ 1051fa8c418SNickeau $dateString .= ":00"; 10637748cd8SNickeau } 10737748cd8SNickeau 10837748cd8SNickeau /** 10937748cd8SNickeau * Timezone 11037748cd8SNickeau */ 1111fa8c418SNickeau if (strlen($dateString) <= 19) { 11237748cd8SNickeau /** 11337748cd8SNickeau * Because this text metadata may be used in other part of the application 11437748cd8SNickeau * We add the timezone to make it whole 11537748cd8SNickeau * And to have a consistent value 11637748cd8SNickeau */ 1171fa8c418SNickeau $dateString .= date('P'); 11837748cd8SNickeau } 11937748cd8SNickeau 1201fa8c418SNickeau 121*26a7e0f8Sgerardnico $dateTime = DateTime::createFromFormat(self::getFormat(), $dateString); 1221fa8c418SNickeau if ($dateTime === false) { 1231fa8c418SNickeau throw new \RuntimeException("The date string ($original) is not one of the valid date format. " . join(", ", self::VALID_FORMATS)); 1241fa8c418SNickeau } 12537748cd8SNickeau return new Iso8601Date($dateTime); 1261fa8c418SNickeau 12737748cd8SNickeau } 12837748cd8SNickeau 1291fa8c418SNickeau public static function createFromTimestamp($timestamp): Iso8601Date 13037748cd8SNickeau { 13137748cd8SNickeau $dateTime = new DateTime(); 13237748cd8SNickeau $dateTime->setTimestamp($timestamp); 13337748cd8SNickeau return new Iso8601Date($dateTime); 13437748cd8SNickeau } 13537748cd8SNickeau 13637748cd8SNickeau /** 13737748cd8SNickeau * And note {@link DATE_ISO8601} 13837748cd8SNickeau * because it's not the compliant IS0-8601 format 13937748cd8SNickeau * as explained here 14037748cd8SNickeau * https://www.php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601 14137748cd8SNickeau * ATOM is 14237748cd8SNickeau * 14337748cd8SNickeau * This format is used by Sqlite, Google and is pretty the standard everywhere 14437748cd8SNickeau * https://www.w3.org/TR/NOTE-datetime 14537748cd8SNickeau */ 1461fa8c418SNickeau public static function getFormat(): string 14737748cd8SNickeau { 14837748cd8SNickeau return DATE_ATOM; 14937748cd8SNickeau } 15037748cd8SNickeau 15137748cd8SNickeau public function isValidDateEntry() 15237748cd8SNickeau { 15337748cd8SNickeau if ($this->dateTime !== false) { 15437748cd8SNickeau return true; 15537748cd8SNickeau } else { 15637748cd8SNickeau return false; 15737748cd8SNickeau } 15837748cd8SNickeau } 15937748cd8SNickeau 16037748cd8SNickeau public function getDateTime() 16137748cd8SNickeau { 16237748cd8SNickeau return $this->dateTime; 16337748cd8SNickeau } 16437748cd8SNickeau 16537748cd8SNickeau public function __toString() 16637748cd8SNickeau { 16737748cd8SNickeau return $this->getDateTime()->format(self::getFormat()); 16837748cd8SNickeau } 16937748cd8SNickeau 17037748cd8SNickeau /** 17137748cd8SNickeau * Shortcut to {@link DateTime::format()} 17237748cd8SNickeau * @param $string 17337748cd8SNickeau * @return string 17437748cd8SNickeau * @link https://php.net/manual/en/datetime.format.php 17537748cd8SNickeau */ 1761fa8c418SNickeau public function format($string): string 17737748cd8SNickeau { 17837748cd8SNickeau return $this->getDateTime()->format($string); 17937748cd8SNickeau } 18037748cd8SNickeau 18137748cd8SNickeau 18237748cd8SNickeau} 183