xref: /template/strap/ComboStrap/Iso8601Date.php (revision 26a7e0f890fa8e62fec018ac7f93dc9387751661)
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