nur-sery/nur_src/date.php

142 lines
4.4 KiB
PHP

<?php
namespace nur;
use nur\b\date\Date as D;
use nur\b\date\Datetime as DT;
use nur\b\date\Elapsed;
/**
* Class date: méthode pour gérer les dates au format français dd/mm/YYYY
*/
class date {
static function is_datetime($date, ?array &$ms=null): bool {
return is_string($date) && preg_match('/^(\d{1,2})[-\/]+(\d{1,2})[-\/]+(\d{2,4}) ([0-9]{1,2})[h:.,]([0-9]{1,2})(?:[:.,]([0-9]{1,2}))?$/', $date, $ms);
}
static function is_date($date, ?array &$ms=null): bool {
return is_string($date) && preg_match('/^(\d{1,2})[-\/]+(\d{1,2})[-\/]+(\d{2,4})(?: 0{1,2}[h:.,]0{1,2}(?:[:.,]0{1,2})?)?$/', $date, $ms);
}
static function datetime(?int $timestamp=null): string {
if ($timestamp === null) $timestamp = time();
return strftime("%d/%m/%Y %H:%M:%S", $timestamp);
}
static function date(?int $timestamp=null): string {
if ($timestamp === null) $timestamp = time();
return strftime("%d/%m/%Y", $timestamp);
}
/**
* corriger une année à deux chiffres qui est située dans le passé et
* retourner l'année à 4 chiffres.
*
* par exemple, si l'année courante est 2019, alors:
* - fix_past_year('18') === '2018'
* - fix_past_year('19') === '1919'
* - fix_past_year('20') === '1920'
*/
static function fix_past_year(int $year): int {
if ($year < 100) {
$y = getdate(); $y = $y["year"];
$r = $y % 100;
$c = $y - $r;
if ($year >= $r) $year += $c - 100;
else $year += $c;
}
return $year;
}
/**
* corriger une année à deux chiffres et retourner l'année à 4 chiffres.
* l'année charnière entre année passée et année future est 70
*
* par exemple, si l'année courante est 2019, alors:
* - fix_past_year('18') === '2018'
* - fix_past_year('19') === '2019'
* - fix_past_year('20') === '2020'
* - fix_past_year('69') === '2069'
* - fix_past_year('70') === '1970'
* - fix_past_year('71') === '1971'
*/
static function fix_any_year(int $year): int {
if ($year < 100) {
$y = getdate(); $y = $y["year"];
$r = $y % 100;
$c = $y - $r;
if ($year >= 70) $year += $c - 100;
else $year += $c;
}
return $year;
}
static function _ms2datetime(array $ms, ?string &$date, ?string &$time): void {
$d = intval($ms[1]);
$m = intval($ms[2]);
$y = self::fix_any_year($ms[3]);
$H = intval($ms[4]);
$M = intval($ms[5]);
$S = intval(isset($ms[6])? $ms[6]: 0);
$date = sprintf("%02d/%02d/%04d", $d, $m, $y);
$time = sprintf("%02d:%02d:%02d", $H, $M, $S);
}
static function _ms2date(array $ms, ?string &$date): void {
$d = intval($ms[1]);
$m = intval($ms[2]);
$y = self::fix_any_year($ms[3]);
$date = sprintf("%02d/%02d/%04d", $d, $m, $y);
}
/**
* Analyser $datetime qui peut être de la forme 'dd/mm/YYYY HH:MM:SS' ou
* 'dd/mm/YYYY' et initialiser les variables $date et $time
*
* s'il n'y a pas de composante 'heure' dans $datetime, $time reçoit la
* valeur null.
*
* retourner true si $datetime était au format attendu, false sinon
*/
static function _split_datetime(?string $datetime, ?string &$date, ?string &$time): bool {
$ms = null;
if (self::is_datetime($datetime, $ms)) {
self::_ms2datetime($ms, $date, $time);
return true;
} elseif (self::is_date($datetime, $ms)) {
self::_ms2date($ms, $date);
$time = null;
return true;
} else {
return false;
}
}
static function split_datetime($datetime, ?string &$date, ?string &$time): bool {
if ($datetime === null || $datetime === false) return false;
else return self::_split_datetime($datetime, $date, $time);
}
static function new($date, bool $null_is_now=false): ?DT {
if ($null_is_now && $date === null) return new DT();
elseif ($date === null) return null;
elseif (is_int($date)) return new DT($date);
return self::is_datetime($date)? new DT($date): new D($date);
}
static function before($date, $other): bool {
if ($other === null) return true;
if ($date === null) return false;
return self::new($date)->before(self::new($other));
}
static function after($date, $other): bool {
if ($other === null) return true;
if ($date === null) return false;
return self::new($date)->after(self::new($other));
}
static function get_elapsed($date, $now=null): Elapsed {
return self::new($date, true)->getElapsed(self::new($now));
}
}