src/Utils/DateHelper.php
<?php
declare(strict_types=1);
namespace Core\Utils;
use DateTime;
use DateTimeZone;
use InvalidArgumentException;
use stdClass;
class DateHelper
{
/**
* Match the pattern for a datetime string in simple date format
*/
public const SIMPLE_DATE = 'Y-m-d';
/**
* Match the pattern for a datetime string in Rfc1123 format
*/
public const RFC1123 = 'D, d M Y H:i:s T';
/**
* Match the pattern for a datetime string in RFC3339 format
*/
public const RFC3339 = 'Y-m-d\TH:i:sP';
/**
* Convert a DateTime object to a string in simple date format
*
* @param DateTime|null $date The DateTime object to convert
*
* @return string|null The datetime as a string in simple date format
* @throws InvalidArgumentException
*/
public static function toSimpleDate(?DateTime $date): ?string
{
if (is_null($date)) {
return null;
}
return $date->format(static::SIMPLE_DATE);
}
/**
* Convert an array of DateTime objects to an array of strings in simple date format
*
* @param array|null $dates The array of DateTime objects to convert
*
* @return array|null The array of datetime strings in simple date format
*/
public static function toSimpleDateArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toSimpleDate'], $dates);
}
/**
* Convert a 2D array of DateTime objects to a 2D array of strings in simple date format
*
* @param array|null $dates The 2D array of DateTime objects to convert
*
* @return array|null The 2D array of datetime strings in simple date format
*/
public static function toSimpleDate2DArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toSimpleDateArray'], $dates);
}
/**
* Parse a datetime string in simple date format to a DateTime object
*
* @param string|null $date A datetime string in simple date format
*
* @return DateTime|null The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromSimpleDate(?string $date): ?DateTime
{
if (is_null($date)) {
return null;
}
$x = DateTime::createFromFormat(static::SIMPLE_DATE, $date);
if ($x instanceof DateTime) {
return $x->setTime(0, 0);
}
throw new InvalidArgumentException('Incorrect format.');
}
/**
* Parse a datetime string in simple date format to a DateTime object
*
* @param string|null $date A datetime string in simple date format
*
* @return DateTime The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromSimpleDateRequired(?string $date): DateTime
{
$result = DateHelper::fromSimpleDate($date);
if (isset($result)) {
return $result;
}
throw new \InvalidArgumentException('Date is null, empty or not in required format.');
}
/**
* Parse an array of datetime strings in simple date format to an array of DateTime objects
*
* @param array|null $dates An array of datetime strings in simple date format
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromSimpleDateArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromSimpleDate'], $dates);
}
/**
* Parse an array of map of datetime strings in simple date format to a 2D array of DateTime objects
*
* @param array|null $dates An array of map of datetime strings in simple date format
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromSimpleDateArrayOfMap(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromSimpleDateMap'], $dates);
}
/**
* Parse a class of datetime strings in simple date format to an array of DateTime objects
*
* @param stdClass|null $dates A class of datetime strings in simple date format
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromSimpleDateMap(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromSimpleDate'], $array);
}
/**
* Parse a map of array of datetime strings in simple date format to a 2D array of DateTime objects
*
* @param stdClass|null $dates A map of array of datetime strings in simple date format
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromSimpleDateMapOfArray(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromSimpleDateArray'], $array);
}
/**
* Convert a DateTime object to a string in Rfc1123 format
*
* @param DateTime|null $date The DateTime object to convert
*
* @return string|null The datetime as a string in Rfc1123 format
* @throws InvalidArgumentException
*/
public static function toRfc1123DateTime(?DateTime $date): ?string
{
if (is_null($date)) {
return null;
}
return $date->setTimeZone(new DateTimeZone('GMT'))->format(static::RFC1123);
}
/**
* Convert an array of DateTime objects to an array of strings in Rfc1123 format
*
* @param array|null $dates The array of DateTime objects to convert
*
* @return array|null The array of datetime strings in Rfc1123 format
*/
public static function toRfc1123DateTimeArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toRfc1123DateTime'], $dates);
}
/**
* Convert a 2D array of DateTime objects to a 2D array of strings in Rfc1123 format
*
* @param array|null $dates The 2D array of DateTime objects to convert
*
* @return array|null The 2D array of datetime strings in Rfc1123 format
*/
public static function toRfc1123DateTime2DArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toRfc1123DateTimeArray'], $dates);
}
/**
* Parse a datetime string in Rfc1123 format to a DateTime object
*
* @param string|null $date A datetime string in Rfc1123 format
*
* @return DateTime|null The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromRfc1123DateTime(?string $date): ?DateTime
{
if (is_null($date)) {
return null;
}
$x = DateTime::createFromFormat(static::RFC1123, $date);
if ($x instanceof DateTime) {
return $x->setTimeZone(new DateTimeZone('GMT'));
}
throw new InvalidArgumentException('Incorrect format.');
}
/**
* Parse a datetime string in Rfc1123 format to a DateTime object
*
* @param string|null $datetime A datetime string in Rfc1123 format
*
* @return DateTime The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromRfc1123DateTimeRequired(?string $datetime): DateTime
{
$result = DateHelper::fromRfc1123DateTime($datetime);
if (isset($result)) {
return $result;
}
throw new \InvalidArgumentException('DateTime is null, empty or not in required format.');
}
/**
* Parse an array of datetime strings in Rfc1123 format to an array of DateTime objects
*
* @param array|null $dates An array of datetime strings in Rfc1123 format
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromRfc1123DateTimeArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromRfc1123DateTime'], $dates);
}
/**
* Parse an array of map of datetime strings in Rfc1123 format to a 2D array of DateTime objects
*
* @param array|null $dates An array of map of datetime strings in Rfc1123 format
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromRfc1123DateTimeArrayOfMap(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromRfc1123DateTimeMap'], $dates);
}
/**
* Parse a class of datetime strings in Rfc1123 format to an array of DateTime objects
*
* @param stdClass|null $dates A class of datetime strings in Rfc1123 format
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromRfc1123DateTimeMap(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromRfc1123DateTime'], $array);
}
/**
* Parse a map of array of datetime strings in Rfc1123 format to a 2D array of DateTime objects
*
* @param stdClass|null $dates A map of array of datetime strings in Rfc1123 format
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromRfc1123DateTimeMapOfArray(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromRfc1123DateTimeArray'], $array);
}
/**
* Convert a DateTime object to a string in Rfc3339 format
*
* @param DateTime|null $date The DateTime object to convert
*
* @return string|null The datetime as a string in Rfc3339 format
* @throws InvalidArgumentException
*/
public static function toRfc3339DateTime(?DateTime $date): ?string
{
if (is_null($date)) {
return null;
}
return $date->setTimeZone(new DateTimeZone('UTC'))->format(static::RFC3339);
}
/**
* Convert an array of DateTime objects to an array of strings in Rfc3339 format
*
* @param array|null $dates The array of DateTime objects to convert
*
* @return array|null The array of datetime strings in Rfc3339 format
*/
public static function toRfc3339DateTimeArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toRfc3339DateTime'], $dates);
}
/**
* Convert a 2D array of DateTime objects to a 2D array of strings in Rfc3339 format
*
* @param array|null $dates The 2D array of DateTime objects to convert
*
* @return array|null The 2D array of datetime strings in Rfc3339 format
*/
public static function toRfc3339DateTime2DArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toRfc3339DateTimeArray'], $dates);
}
/**
* Parse a datetime string in Rfc3339 format to a DateTime object
*
* @param string|null $date A datetime string in Rfc3339 format
*
* @return DateTime|null The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromRfc3339DateTime(?string $date): ?DateTime
{
if (is_null($date)) {
return null;
}
// Check for timezone information and append it if missing
if (empty(preg_match("/T.*[+-]|T.*Z/", $date))) {
$date .= 'Z';
}
$x = DateTime::createFromFormat(static::RFC3339, $date);
if ($x instanceof DateTime) {
return $x->setTimeZone(new DateTimeZone('UTC'));
}
$x = DateTime::createFromFormat("Y-m-d\TH:i:s.uP", $date); // parse with up to 6 microseconds
if ($x instanceof DateTime) {
return $x->setTimeZone(new DateTimeZone('UTC'));
}
$x = DateTime::createFromFormat("Y-m-d\TH:i:s.uuP", $date); // parse with up to 12 microseconds
if ($x instanceof DateTime) {
return $x->setTimeZone(new DateTimeZone('UTC'));
}
throw new InvalidArgumentException('Incorrect format.');
}
/**
* Parse a datetime string in Rfc3339 format to a DateTime object
*
* @param string|null $datetime A datetime string in Rfc3339 format
*
* @return DateTime The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromRfc3339DateTimeRequired(?string $datetime): DateTime
{
$result = DateHelper::fromRfc3339DateTime($datetime);
if (isset($result)) {
return $result;
}
throw new \InvalidArgumentException('DateTime is null, empty or not in required format.');
}
/**
* Parse an array of datetime strings in Rfc3339 format to an array of DateTime objects
*
* @param array|null $dates An array of datetime strings in Rfc3339 format
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromRfc3339DateTimeArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromRfc3339DateTime'], $dates);
}
/**
* Parse an array of map of datetime strings in Rfc3339 format to a 2D array DateTime objects
*
* @param array|null $dates An array of map of datetime strings in Rfc3339 format
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromRfc3339DateTimeArrayOfMap(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromRfc3339DateTimeMap'], $dates);
}
/**
* Parse a class of datetime strings in Rfc3339 format to an array of DateTime objects
*
* @param stdClass|null $dates A class of datetime strings in Rfc3339 format
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromRfc3339DateTimeMap(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromRfc3339DateTime'], $array);
}
/**
* Parse a map of array of datetime strings in Rfc3339 format to a 2D array of DateTime objects
*
* @param stdClass|null $dates A map of array of datetime strings in Rfc3339 format
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromRfc3339DateTimeMapOfArray(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromRfc3339DateTimeArray'], $array);
}
/**
* Convert a DateTime object to a Unix Timestamp
*
* @param DateTime|null $date The DateTime object to convert
*
* @return int|null The converted Unix Timestamp
* @throws InvalidArgumentException
*/
public static function toUnixTimestamp(?DateTime $date): ?int
{
if (is_null($date)) {
return null;
}
return $date->getTimestamp();
}
/**
* Convert an array of DateTime objects to an array of Unix timestamps
*
* @param array|null $dates The array of DateTime objects to convert
*
* @return array|null The array of integers representing date-time in Unix timestamp
*/
public static function toUnixTimestampArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toUnixTimestamp'], $dates);
}
/**
* Convert a 2D array of DateTime objects to a 2D array of Unix timestamps
*
* @param array|null $dates The 2D array of DateTime objects to convert
*
* @return array|null The 2D array of integers representing date-time in Unix timestamp
*/
public static function toUnixTimestamp2DArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'toUnixTimestampArray'], $dates);
}
/**
* Parse a Unix Timestamp to a DateTime object
*
* @param string|null $date The Unix Timestamp
*
* @return DateTime|null The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromUnixTimestamp(?string $date): ?DateTime
{
if (empty($date)) {
return null;
}
$x = DateTime::createFromFormat("U", $date);
if ($x instanceof DateTime) {
return $x;
}
throw new InvalidArgumentException('Incorrect format.');
}
/**
* Parse a Unix Timestamp to a DateTime object
*
* @param string|null $datetime The Unix Timestamp
*
* @return DateTime The parsed DateTime object
* @throws InvalidArgumentException
*/
public static function fromUnixTimestampRequired(?string $datetime): DateTime
{
$result = DateHelper::fromUnixTimestamp($datetime);
if (isset($result)) {
return $result;
}
throw new \InvalidArgumentException('DateTime is null, empty or not in required format.');
}
/**
* Parse an array of Unix Timestamps to an array of DateTime objects
*
* @param array|null $dates An array of Unix Timestamps
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromUnixTimestampArray(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromUnixTimestamp'], array_map('strval', $dates));
}
/**
* Parse an array of map of Unix Timestamps to a 2D array of DateTime objects
*
* @param array|null $dates An array of map of Unix Timestamps
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromUnixTimestampArrayOfMap(?array $dates): ?array
{
if (is_null($dates)) {
return null;
}
return array_map([self::class, 'fromUnixTimestampMap'], $dates);
}
/**
* Parse a class of Unix Timestamps to an array of DateTime objects
*
* @param stdClass|null $dates A class of Unix Timestamps
*
* @return array|null An array of parsed DateTime objects
*/
public static function fromUnixTimestampMap(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromUnixTimestamp'], array_map('strval', $array));
}
/**
* Parse a map of array of Unix Timestamps to a 2D array of DateTime objects
*
* @param stdClass|null $dates A map of array of Unix Timestamps
*
* @return array|null A 2D array of parsed DateTime objects
*/
public static function fromUnixTimestampMapOfArray(?stdClass $dates): ?array
{
if (is_null($dates)) {
return null;
}
$array = json_decode(json_encode($dates), true);
return array_map([self::class, 'fromUnixTimestampArray'], $array);
}
}