support délai infini
This commit is contained in:
parent
24efdddb68
commit
2f3a21aad4
@ -30,6 +30,11 @@ class Delay {
|
||||
else return new static($delay, $from);
|
||||
}
|
||||
|
||||
/**
|
||||
* pour une durée infinie, l'intervalle est toujours de 1000 ans dans le futur
|
||||
*/
|
||||
const INF_INTERVAL = "P1000Y";
|
||||
|
||||
/** valeurs par défaut de x et y pour les unités supportées */
|
||||
const DEFAULTS = [
|
||||
"w" => [0, 5],
|
||||
@ -89,12 +94,9 @@ class Delay {
|
||||
|
||||
function __construct($delay, ?DateTimeInterface $from=null) {
|
||||
$from = MutableDateTime::with($from)->clone(true);
|
||||
if ($delay === "INF") {
|
||||
$dest = $from;
|
||||
# rajouter 1000 ans pour ne pas dépasser la capacité
|
||||
#XXX avant, c'était 9999 ans, mais getDest() provoque une exception parce
|
||||
# que DateTime ne sait pas traiter une valeur flottante
|
||||
$dest->add(new DateInterval("P1000Y"));
|
||||
if ($delay === null || $delay === "INF") {
|
||||
# $dest === null signifie un délai infini
|
||||
$dest = null;
|
||||
$repr = "INF";
|
||||
} elseif (is_int($delay)) {
|
||||
[$dest, $repr] = self::compute_dest($delay, "s", null, $from);
|
||||
@ -118,38 +120,51 @@ class Delay {
|
||||
}
|
||||
|
||||
function __clone() {
|
||||
$this->dest = clone $this->dest;
|
||||
if ($this->dest !== null) {
|
||||
$this->dest = clone $this->dest;
|
||||
}
|
||||
}
|
||||
|
||||
function __serialize(): array {
|
||||
return [$this->dest->clone(), $this->repr];
|
||||
$dest = $this->dest;
|
||||
if ($dest !== null) $dest = $dest->clone();
|
||||
return [$dest, $this->repr];
|
||||
}
|
||||
function __unserialize(array $data): void {
|
||||
[$dest, $this->repr] = $data;
|
||||
$this->dest = $dest->clone(true);
|
||||
if ($dest !== null) $dest = $dest->clone(true);
|
||||
$this->dest = $dest;
|
||||
}
|
||||
|
||||
/** @var MutableDateTime */
|
||||
protected $dest;
|
||||
protected ?MutableDateTime $dest;
|
||||
|
||||
function getDest(): DateTime {
|
||||
return $this->dest->clone();
|
||||
$dest = $this->dest;
|
||||
if ($dest === null) {
|
||||
$dest = new MutableDateTime();
|
||||
$dest->add(new \DateInterval(self::INF_INTERVAL));
|
||||
}
|
||||
return $dest->clone();
|
||||
}
|
||||
|
||||
function addDuration($duration): self {
|
||||
if (is_numeric($duration) && $duration < 0) {
|
||||
$this->dest->sub(DateInterval::with(-$duration));
|
||||
} else {
|
||||
$this->dest->add(DateInterval::with($duration));
|
||||
if ($this->dest !== null) {
|
||||
if (is_numeric($duration) && $duration < 0) {
|
||||
$this->dest->sub(DateInterval::with(-$duration));
|
||||
} else {
|
||||
$this->dest->add(DateInterval::with($duration));
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
function subDuration($duration): self {
|
||||
if (is_numeric($duration) && $duration < 0) {
|
||||
$this->dest->add(DateInterval::with(-$duration));
|
||||
} else {
|
||||
$this->dest->sub(DateInterval::with($duration));
|
||||
if ($this->dest !== null) {
|
||||
if (is_numeric($duration) && $duration < 0) {
|
||||
$this->dest->add(DateInterval::with(-$duration));
|
||||
} else {
|
||||
$this->dest->sub(DateInterval::with($duration));
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@ -161,23 +176,20 @@ class Delay {
|
||||
return $this->repr;
|
||||
}
|
||||
|
||||
protected function _getDiff(?DateTimeInterface $now=null): \DateInterval {
|
||||
$now ??= new \DateTime();
|
||||
return $this->dest->diff($now);
|
||||
}
|
||||
|
||||
/** retourner true si le délai imparti est écoulé */
|
||||
function isElapsed(?DateTimeInterface $now=null): bool {
|
||||
if ($this->repr === "INF") return false;
|
||||
else return $this->_getDiff($now)->invert == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* retourner l'intervalle entre le moment courant et la destination.
|
||||
*
|
||||
* l'intervalle est négatif si le délai n'est pas écoulé, positif sinon
|
||||
*/
|
||||
function getDiff(?DateTimeInterface $now=null): DateInterval {
|
||||
return new DateInterval($this->_getDiff($now));
|
||||
$dest = $this->dest;
|
||||
if ($dest !== null) return $dest->diff($now ?? new \DateTime());
|
||||
else return new DateInterval("-".self::INF_INTERVAL);
|
||||
}
|
||||
|
||||
/** retourner true si le délai imparti est écoulé */
|
||||
function isElapsed(?DateTimeInterface $now=null): bool {
|
||||
if ($this->dest === null) return false;
|
||||
else return $this->getDiff($now)->invert == 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,3 @@
|
||||
# nulib\php\time
|
||||
|
||||
* refaire l'implémentation pour les délais INF. c'est un cas particulier qui
|
||||
n'est jamais atteint. il faut donc implémenter un traitement spécifique dans
|
||||
chaque méthode (i.e `if ($repr === "INF") { doSomething() }`)
|
||||
* la destination est toujours 1000 ans dans le futur
|
||||
* la différence est toujours de 1000 ans
|
||||
|
||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
|
@ -83,4 +83,19 @@ class DelayTest extends TestCase {
|
||||
$unserialized = unserialize($serialized);
|
||||
self::assertEquals($delay, $unserialized);
|
||||
}
|
||||
|
||||
function testInf() {
|
||||
$delay = new Delay("INF");
|
||||
self::assertSame("INF", strval($delay));
|
||||
self::assertFalse($delay->isElapsed());
|
||||
|
||||
$diff = $delay->getDiff();
|
||||
self::assertSame("-P1000YT", strval($diff));
|
||||
|
||||
$serialized = serialize($delay);
|
||||
self::assertSame('O:20:"nulib\php\time\Delay":2:{i:0;N;i:1;s:3:"INF";}', $serialized);
|
||||
echo "serialized: $serialized\n";
|
||||
$unserialized = unserialize($serialized);
|
||||
self::assertEquals($delay, $unserialized);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user