xref: /template/strap/ComboStrap/Iso8601Date.php (revision c3437056399326d621a01da73b649707fbb0ae69)
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
59*c3437056SNickeau    /**
60*c3437056SNickeau     * @param null $dateString
61*c3437056SNickeau     * @return Iso8601Date
62*c3437056SNickeau     * @throws ExceptionCombo if the format is not supported
63*c3437056SNickeau     */
64*c3437056SNickeau    public static function createFromString($dateString = null): Iso8601Date
6537748cd8SNickeau    {
661fa8c418SNickeau
671fa8c418SNickeau        $original = $dateString;
681fa8c418SNickeau
691fa8c418SNickeau        if ($dateString === null) {
7037748cd8SNickeau            return new Iso8601Date();
7137748cd8SNickeau        }
7237748cd8SNickeau
7337748cd8SNickeau        /**
7437748cd8SNickeau         * Time ?
7537748cd8SNickeau         * (ie only YYYY-MM-DD)
7637748cd8SNickeau         */
771fa8c418SNickeau        if (strlen($dateString) <= 10) {
7837748cd8SNickeau            /**
7937748cd8SNickeau             * We had the time to 00:00:00
8037748cd8SNickeau             * because {@link DateTime::createFromFormat} with a format of
8137748cd8SNickeau             * Y-m-d will be using the actual time otherwise
8237748cd8SNickeau             *
8337748cd8SNickeau             */
841fa8c418SNickeau            $dateString .= "T00:00:00";
851fa8c418SNickeau        }
861fa8c418SNickeau
871fa8c418SNickeau        /**
881fa8c418SNickeau         * Space as T
891fa8c418SNickeau         */
901fa8c418SNickeau        $dateString = str_replace(" ", "T", $dateString);
911fa8c418SNickeau
921fa8c418SNickeau
931fa8c418SNickeau        if (strlen($dateString) <= 13) {
941fa8c418SNickeau            /**
951fa8c418SNickeau             * We had the time to 00:00:00
961fa8c418SNickeau             * because {@link DateTime::createFromFormat} with a format of
971fa8c418SNickeau             * Y-m-d will be using the actual time otherwise
981fa8c418SNickeau             *
991fa8c418SNickeau             */
1001fa8c418SNickeau            $dateString .= ":00:00";
1011fa8c418SNickeau        }
1021fa8c418SNickeau
1031fa8c418SNickeau        if (strlen($dateString) <= 16) {
1041fa8c418SNickeau            /**
1051fa8c418SNickeau             * We had the time to 00:00:00
1061fa8c418SNickeau             * because {@link DateTime::createFromFormat} with a format of
1071fa8c418SNickeau             * Y-m-d will be using the actual time otherwise
1081fa8c418SNickeau             *
1091fa8c418SNickeau             */
1101fa8c418SNickeau            $dateString .= ":00";
11137748cd8SNickeau        }
11237748cd8SNickeau
11337748cd8SNickeau        /**
11437748cd8SNickeau         * Timezone
11537748cd8SNickeau         */
1161fa8c418SNickeau        if (strlen($dateString) <= 19) {
11737748cd8SNickeau            /**
11837748cd8SNickeau             * Because this text metadata may be used in other part of the application
11937748cd8SNickeau             * We add the timezone to make it whole
12037748cd8SNickeau             * And to have a consistent value
12137748cd8SNickeau             */
1221fa8c418SNickeau            $dateString .= date('P');
12337748cd8SNickeau        }
12437748cd8SNickeau
1251fa8c418SNickeau
12626a7e0f8Sgerardnico        $dateTime = DateTime::createFromFormat(self::getFormat(), $dateString);
1271fa8c418SNickeau        if ($dateTime === false) {
128*c3437056SNickeau            $message = "The date string ($original) is not in a valid date format. (" . join(", ", self::VALID_FORMATS) . ")";
129*c3437056SNickeau            throw new ExceptionCombo($message, self::CANONICAL);
1301fa8c418SNickeau        }
13137748cd8SNickeau        return new Iso8601Date($dateTime);
1321fa8c418SNickeau
13337748cd8SNickeau    }
13437748cd8SNickeau
1351fa8c418SNickeau    public static function createFromTimestamp($timestamp): Iso8601Date
13637748cd8SNickeau    {
13737748cd8SNickeau        $dateTime = new DateTime();
13837748cd8SNickeau        $dateTime->setTimestamp($timestamp);
13937748cd8SNickeau        return new Iso8601Date($dateTime);
14037748cd8SNickeau    }
14137748cd8SNickeau
14237748cd8SNickeau    /**
14337748cd8SNickeau     * And note {@link DATE_ISO8601}
14437748cd8SNickeau     * because it's not the compliant IS0-8601 format
14537748cd8SNickeau     * as explained here
14637748cd8SNickeau     * https://www.php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601
14737748cd8SNickeau     * ATOM is
14837748cd8SNickeau     *
14937748cd8SNickeau     * This format is used by Sqlite, Google and is pretty the standard everywhere
15037748cd8SNickeau     * https://www.w3.org/TR/NOTE-datetime
15137748cd8SNickeau     */
1521fa8c418SNickeau    public static function getFormat(): string
15337748cd8SNickeau    {
15437748cd8SNickeau        return DATE_ATOM;
15537748cd8SNickeau    }
15637748cd8SNickeau
157*c3437056SNickeau    public static function isValid($value): bool
158*c3437056SNickeau    {
159*c3437056SNickeau        $dateObject = Iso8601Date::createFromString($value);
160*c3437056SNickeau        return $dateObject->isValidDateEntry();
161*c3437056SNickeau    }
162*c3437056SNickeau
163*c3437056SNickeau    public function isValidDateEntry(): bool
16437748cd8SNickeau    {
16537748cd8SNickeau        if ($this->dateTime !== false) {
16637748cd8SNickeau            return true;
16737748cd8SNickeau        } else {
16837748cd8SNickeau            return false;
16937748cd8SNickeau        }
17037748cd8SNickeau    }
17137748cd8SNickeau
172*c3437056SNickeau    public static function createFromDateTime(DateTime $dateTime): Iso8601Date
173*c3437056SNickeau    {
174*c3437056SNickeau        return new Iso8601Date($dateTime);
175*c3437056SNickeau    }
176*c3437056SNickeau
177*c3437056SNickeau    public static function createFromNow(): Iso8601Date
178*c3437056SNickeau    {
179*c3437056SNickeau        return new Iso8601Date();
180*c3437056SNickeau    }
181*c3437056SNickeau
18237748cd8SNickeau    public function getDateTime()
18337748cd8SNickeau    {
18437748cd8SNickeau        return $this->dateTime;
18537748cd8SNickeau    }
18637748cd8SNickeau
18737748cd8SNickeau    public function __toString()
18837748cd8SNickeau    {
18937748cd8SNickeau        return $this->getDateTime()->format(self::getFormat());
19037748cd8SNickeau    }
19137748cd8SNickeau
19237748cd8SNickeau    /**
19337748cd8SNickeau     * Shortcut to {@link DateTime::format()}
19437748cd8SNickeau     * @param $string
19537748cd8SNickeau     * @return string
19637748cd8SNickeau     * @link https://php.net/manual/en/datetime.format.php
19737748cd8SNickeau     */
1981fa8c418SNickeau    public function format($string): string
19937748cd8SNickeau    {
20037748cd8SNickeau        return $this->getDateTime()->format($string);
20137748cd8SNickeau    }
20237748cd8SNickeau
203*c3437056SNickeau    public function toString()
204*c3437056SNickeau    {
205*c3437056SNickeau        return $this->__toString();
206*c3437056SNickeau    }
207*c3437056SNickeau
208*c3437056SNickeau
209*c3437056SNickeau
21037748cd8SNickeau
21137748cd8SNickeau}
212