refactor: use epoch timestamp
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -15,6 +15,7 @@ use KTXF\Resource\Identifier\CollectionIdentifierInterface;
|
|||||||
use KTXF\Resource\Identifier\EntityIdentifierInterface;
|
use KTXF\Resource\Identifier\EntityIdentifierInterface;
|
||||||
use KTXF\Resource\Identifier\ResourceIdentifier;
|
use KTXF\Resource\Identifier\ResourceIdentifier;
|
||||||
use KTXF\Resource\Identifier\ServiceIdentifier;
|
use KTXF\Resource\Identifier\ServiceIdentifier;
|
||||||
|
use KTXF\Utile\Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Node Base Class
|
* Abstract Node Base Class
|
||||||
@@ -119,18 +120,14 @@ abstract class NodeBaseAbstract implements NodeBaseInterface {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function created(): DateTimeImmutable|null {
|
public function created(): DateTimeImmutable|null {
|
||||||
return isset($this->data[static::PROPERTY_CREATED])
|
return Timestamp::toDateTime($this->data[static::PROPERTY_CREATED] ?? null);
|
||||||
? new DateTimeImmutable($this->data[static::PROPERTY_CREATED])
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function modified(): DateTimeImmutable|null {
|
public function modified(): DateTimeImmutable|null {
|
||||||
return isset($this->data[static::PROPERTY_MODIFIED])
|
return Timestamp::toDateTime($this->data[static::PROPERTY_MODIFIED] ?? null);
|
||||||
? new DateTimeImmutable($this->data[static::PROPERTY_MODIFIED])
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\Resource\Provider\Node;
|
namespace KTXF\Resource\Provider\Node;
|
||||||
|
|
||||||
|
use KTXF\Utile\Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Node Mutable Class
|
* Abstract Node Mutable Class
|
||||||
*
|
*
|
||||||
@@ -56,19 +58,21 @@ abstract class NodeMutableAbstract extends NodeBaseAbstract implements NodeMutab
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data[static::PROPERTY_CREATED])) {
|
if (isset($data[static::PROPERTY_CREATED])) {
|
||||||
if (!is_string($data[static::PROPERTY_CREATED])) {
|
$created = Timestamp::normalize($data[static::PROPERTY_CREATED]);
|
||||||
throw new \InvalidArgumentException("Created date must be a string in ISO 8601 format");
|
if ($created === null) {
|
||||||
|
throw new \InvalidArgumentException("Created date must be a valid epoch millisecond or ISO 8601 date");
|
||||||
}
|
}
|
||||||
$this->data[static::PROPERTY_CREATED] = $data[static::PROPERTY_CREATED];
|
$this->data[static::PROPERTY_CREATED] = $created;
|
||||||
} else {
|
} else {
|
||||||
$this->data[static::PROPERTY_CREATED] = null;
|
$this->data[static::PROPERTY_CREATED] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data[static::PROPERTY_MODIFIED])) {
|
if (isset($data[static::PROPERTY_MODIFIED])) {
|
||||||
if (!is_string($data[static::PROPERTY_MODIFIED])) {
|
$modified = Timestamp::normalize($data[static::PROPERTY_MODIFIED]);
|
||||||
throw new \InvalidArgumentException("Modified date must be a string in ISO 8601 format");
|
if ($modified === null) {
|
||||||
|
throw new \InvalidArgumentException("Modified date must be a valid epoch millisecond or ISO 8601 date");
|
||||||
}
|
}
|
||||||
$this->data[static::PROPERTY_MODIFIED] = $data[static::PROPERTY_MODIFIED];
|
$this->data[static::PROPERTY_MODIFIED] = $modified;
|
||||||
} else {
|
} else {
|
||||||
$this->data[static::PROPERTY_MODIFIED] = null;
|
$this->data[static::PROPERTY_MODIFIED] = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,32 +9,30 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\Resource\Range;
|
namespace KTXF\Resource\Range;
|
||||||
|
|
||||||
use DateTimeInterface;
|
|
||||||
|
|
||||||
interface IRangeDate extends IRange {
|
interface IRangeDate extends IRange {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function getStart(): DateTimeInterface;
|
public function getStart(): int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setStart(DateTimeInterface $value): void;
|
public function setStart(int $value): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function getEnd(): DateTimeInterface;
|
public function getEnd(): int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setEnd(DateTimeInterface $value): void;
|
public function setEnd(int $value): void;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\Resource\Range;
|
namespace KTXF\Resource\Range;
|
||||||
|
|
||||||
use DateTimeImmutable;
|
use KTXF\Utile\Timestamp;
|
||||||
use DateTimeInterface;
|
|
||||||
|
|
||||||
class RangeDate extends Range implements IRangeDate {
|
class RangeDate extends Range implements IRangeDate {
|
||||||
|
|
||||||
protected DateTimeInterface $start;
|
protected int $start;
|
||||||
protected DateTimeInterface $end;
|
protected int $end;
|
||||||
|
|
||||||
public function jsonDeserialize(array|string $data): static {
|
public function jsonDeserialize(array|string $data): static {
|
||||||
if (is_string($data)) {
|
if (is_string($data)) {
|
||||||
@@ -23,10 +22,16 @@ class RangeDate extends Range implements IRangeDate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['start'])) {
|
if (isset($data['start'])) {
|
||||||
$this->setStart(new DateTimeImmutable($data['start']));
|
$start = Timestamp::normalize($data['start']);
|
||||||
|
if ($start !== null) {
|
||||||
|
$this->setStart($start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isset($data['end'])) {
|
if (isset($data['end'])) {
|
||||||
$this->setEnd(new DateTimeImmutable($data['end']));
|
$end = Timestamp::normalize($data['end']);
|
||||||
|
if ($end !== null) {
|
||||||
|
$this->setEnd($end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@@ -46,7 +51,7 @@ class RangeDate extends Range implements IRangeDate {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function getStart(): DateTimeInterface {
|
public function getStart(): int {
|
||||||
return $this->start;
|
return $this->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +60,7 @@ class RangeDate extends Range implements IRangeDate {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setStart(DateTimeInterface $value): void {
|
public function setStart(int $value): void {
|
||||||
$this->start = $value;
|
$this->start = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +69,7 @@ class RangeDate extends Range implements IRangeDate {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function getEnd(): DateTimeInterface {
|
public function getEnd(): int {
|
||||||
return $this->end;
|
return $this->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +78,7 @@ class RangeDate extends Range implements IRangeDate {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setEnd(DateTimeInterface $value): void {
|
public function setEnd(int $value): void {
|
||||||
$this->end = $value;
|
$this->end = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace KTXF\Utile;
|
||||||
|
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use DateTimeZone;
|
||||||
|
|
||||||
|
final class Timestamp {
|
||||||
|
|
||||||
|
public static function normalize(mixed $value): ?int {
|
||||||
|
if ($value instanceof DateTimeInterface) {
|
||||||
|
return self::toEpoch($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int($value)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_float($value)) {
|
||||||
|
return (int)$value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value)) {
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return (int)$value;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return self::toEpoch(new DateTimeImmutable($value));
|
||||||
|
} catch (\Exception) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function toEpoch(DateTimeInterface $moment): int {
|
||||||
|
$utcMoment = DateTimeImmutable::createFromInterface($moment)
|
||||||
|
->setTimezone(new DateTimeZone('UTC'));
|
||||||
|
return ((int)$utcMoment->format('U') * 1000) + (int)$utcMoment->format('v');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function toDateTime(mixed $value): ?DateTimeImmutable {
|
||||||
|
if ($value instanceof DateTimeImmutable) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value instanceof DateTimeInterface) {
|
||||||
|
return DateTimeImmutable::createFromInterface($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int($value) || is_float($value) || (is_string($value) && is_numeric($value))) {
|
||||||
|
$milliseconds = (int)$value;
|
||||||
|
$seconds = intdiv($milliseconds, 1000);
|
||||||
|
$microseconds = ($milliseconds % 1000) * 1000;
|
||||||
|
return DateTimeImmutable::createFromFormat(
|
||||||
|
'U u',
|
||||||
|
sprintf('%d %06d', $seconds, $microseconds),
|
||||||
|
new DateTimeZone('UTC')
|
||||||
|
) ?: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) && trim($value) !== '') {
|
||||||
|
try {
|
||||||
|
return new DateTimeImmutable($value);
|
||||||
|
} catch (\Exception) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function toIso8601(int $value): ?string {
|
||||||
|
$moment = self::toDateTime($value);
|
||||||
|
return $moment?->format('Y-m-d\TH:i:s.v\Z');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user