From b71e879823777683aa1802ab2041e6c405069e04 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 24 Jun 2025 04:13:09 +0400 Subject: [PATCH] =?UTF-8?q?la=20datetime=20est=20dans=20le=20timezone=20pa?= =?UTF-8?q?r=20d=C3=A9faut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/src/db/CapacitorStorage.php | 2 +- php/src/db/pgsql/PgsqlStorage.php | 2 +- php/src/php/time/DateTime.php | 49 ++++++++++++++++++++++++++----- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/php/src/db/CapacitorStorage.php b/php/src/db/CapacitorStorage.php index c948691..cedf8b2 100644 --- a/php/src/db/CapacitorStorage.php +++ b/php/src/db/CapacitorStorage.php @@ -45,7 +45,7 @@ abstract class CapacitorStorage { const GENLIC_DEFINITION = "varchar(80)"; const GENLIB_DEFINITION = "varchar(255)"; const GENTEXT_DEFINITION = "mediumtext"; - const GENBOOL_DEFINITION = "integer(1)"; + const GENBOOL_DEFINITION = "integer(1) default 0"; const GENUUID_DEFINITION = "varchar(36)"; protected static function gencol($def): string { diff --git a/php/src/db/pgsql/PgsqlStorage.php b/php/src/db/pgsql/PgsqlStorage.php index 649b3eb..6d0f8a3 100644 --- a/php/src/db/pgsql/PgsqlStorage.php +++ b/php/src/db/pgsql/PgsqlStorage.php @@ -11,7 +11,7 @@ class PgsqlStorage extends CapacitorStorage { const SERTS_DEFINITION = "timestamp"; const GENSERIAL_DEFINITION = "serial primary key"; const GENTEXT_DEFINITION = "text"; - const GENBOOL_DEFINITION = "boolean"; + const GENBOOL_DEFINITION = "boolean default false"; const GENUUID_DEFINITION = "uuid"; function __construct($pgsql) { diff --git a/php/src/php/time/DateTime.php b/php/src/php/time/DateTime.php index 1fcd632..816b6bf 100644 --- a/php/src/php/time/DateTime.php +++ b/php/src/php/time/DateTime.php @@ -4,6 +4,7 @@ namespace nulib\php\time; use DateTimeInterface; use DateTimeZone; use InvalidArgumentException; +use nulib\str; /** * Class DateTime: une date et une heure @@ -32,7 +33,7 @@ class DateTime extends \DateTime { const DMY_PATTERN = '/^(\d+)\/(\d+)(?:\/(\d+))?$/'; const YMD_PATTERN = '/^((?:\d{2})?\d{2})(\d{2})(\d{2})$/'; const DMYHIS_PATTERN = '/^(\d+)\/(\d+)(?:\/(\d+))? +(\d+)[h:.](\d+)(?:[:.](\d+))?$/'; - const YMDHISZ_PATTERN = '/^((?:\d{2})?\d{2})(\d{2})(\d{2})[tT](\d{2})(\d{2})(\d{2})?([zZ])?$/'; + const YMDHISZ_PATTERN = '/^((?:\d{2})?\d{2})-?(\d{2})-?(\d{2})[tT](\d{2}):?(\d{2}):?(\d{2})?([zZ]|\+\d{2}:?\d{2})?$/'; protected static function get_value(array $datetime, ?string $key, ?string $k, ?int $index) { @@ -206,16 +207,34 @@ class DateTime extends \DateTime { return $year; } - function __construct($datetime="now", DateTimeZone $timezone=null) { + static function fix_z(?string $Z): ?string { + $Z = strtoupper($Z); + str::del_prefix($Z, "+"); + if (preg_match('/^\d{4}$/', $Z)) { + $Z = substr($Z, 0, 2).":".substr($Z, 2); + } + if ($Z === "Z" || $Z === "UTC" || $Z === "00:00") return "UTC"; + return "GMT+$Z"; + } + + function __construct($datetime="now", DateTimeZone $timezone=null, ?bool $forceLocalTimezone=null) { + $forceLocalTimezone ??= $timezone === null; + if ($forceLocalTimezone) { + $setTimezone = $timezone; + $timezone = null; + } + $datetime ??= "now"; if ($datetime instanceof \DateTimeInterface) { - if ($timezone === null) $timezone = $datetime->getTimezone(); + $timezone ??= $datetime->getTimezone(); parent::__construct(); $this->setTimestamp($datetime->getTimestamp()); $this->setTimezone($timezone); + } elseif (is_int($datetime)) { parent::__construct("now", $timezone); $this->setTimestamp($datetime); + } elseif (is_string($datetime)) { $Y = $H = $Z = null; if (preg_match(self::DMY_PATTERN, $datetime, $ms)) { @@ -253,22 +272,30 @@ class DateTime extends \DateTime { if ($Y !== null) { if ($H === null) $datetime = sprintf("%04d-%02d-%02d", $Y, $m, $d); else $datetime = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $Y, $m, $d, $H, $M, $S); - if ($Z !== null) $timezone = new DateTimeZone("UTC"); + if ($Z !== null) $timezone = new DateTimeZone(self::fix_z($Z)); } parent::__construct($datetime, $timezone); + } elseif (is_array($datetime) && ($datetime = self::parse_array($datetime)) !== null) { - [$Y, $m, $d, $H, $M, $S, $tz] = $datetime; + $setTimezone = $timezone; + $timezone = null; + [$Y, $m, $d, $H, $M, $S, $Z] = $datetime; if ($H === null && $M === null && $S === null) { $datetime = sprintf("%04d-%02d-%02d", $Y, $m, $d); } else { $datetime = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $Y, $m, $d, $H ?? 0, $M ?? 0, $S ?? 0); } - if ($tz === "Z" || $tz === "z") $tz = "UTC"; - $timezone = $tz !== null? new DateTimeZone($tz): null; + if ($Z !== null) $timezone = new DateTimeZone(self::fix_z($Z)); parent::__construct($datetime, $timezone); + } else { throw new InvalidArgumentException("datetime must be a string or an instance of DateTimeInterface"); } + + if ($forceLocalTimezone) { + $setTimezone ??= new DateTimeZone(date_default_timezone_get()); + $this->setTimezone($setTimezone); + } } function diff($target, $absolute=false): DateInterval { @@ -276,7 +303,13 @@ class DateTime extends \DateTime { } function format($format=self::DEFAULT_FORMAT): string { - return \DateTime::format($format); + if (array_key_exists($format, self::INT_FORMATS)) { + $format = self::INT_FORMATS[$format]; + } elseif (array_key_exists($format, self::STRING_FORMATS)) { + $format = self::STRING_FORMATS[$format]; + } + if (is_callable($format)) return $format($this); + else return \DateTime::format($format); } /**