2017-05-21 21:16:32 +00:00
< ? php
declare ( strict_types = 1 );
namespace JKingWeb\Arsse\Misc ;
2017-07-17 11:47:57 +00:00
class Date {
2017-10-19 19:18:58 +00:00
const FORMAT = [ // in out
'iso8601' => [ " !Y-m-d \T H:i:s " , " Y-m-d \T H:i:s \ Z " ], // NOTE: ISO 8601 dates require special input processing because of varying formats for timezone offsets
'iso8601m' => [ " !Y-m-d \T H:i:s.u " , " Y-m-d \T H:i:s.u \ Z " ], // NOTE: ISO 8601 dates require special input processing because of varying formats for timezone offsets
'microtime' => [ " U.u " , " 0.u00 U " ], // NOTE: the actual input format at the user level matches the output format; pre-processing is required for PHP not to fail
'http' => [ " !D, d M Y H:i:s \ G \ M \T " , " D, d M Y H:i:s \ G \ M \T " ],
'sql' => [ " !Y-m-d H:i:s " , " Y-m-d H:i:s " ],
'date' => [ " !Y-m-d " , " Y-m-d " ],
'time' => [ " !H:i:s " , " H:i:s " ],
'unix' => [ " U " , " U " ],
'float' => [ " U.u " , " U.u " ],
];
2017-08-29 14:50:31 +00:00
public static function transform ( $date , string $outFormat = null , string $inFormat = null , bool $inLocal = false ) {
2017-07-17 11:47:57 +00:00
$date = self :: normalize ( $date , $inFormat , $inLocal );
2017-08-29 14:50:31 +00:00
if ( is_null ( $date ) || is_null ( $outFormat )) {
2017-07-21 02:40:09 +00:00
return $date ;
}
2017-07-07 19:25:47 +00:00
$outFormat = strtolower ( $outFormat );
2017-08-29 14:50:31 +00:00
if ( $outFormat == " unix " ) {
2017-07-21 02:40:09 +00:00
return $date -> getTimestamp ();
}
2017-07-07 19:25:47 +00:00
switch ( $outFormat ) {
2017-05-21 21:16:32 +00:00
case 'http' : $f = " D, d M Y H:i:s \ G \ M \T " ; break ;
2017-10-19 19:18:58 +00:00
case 'iso8601' : $f = " Y-m-d \T H:i:s " ; break ;
2017-05-21 21:16:32 +00:00
case 'sql' : $f = " Y-m-d H:i:s " ; break ;
case 'date' : $f = " Y-m-d " ; break ;
case 'time' : $f = " H:i:s " ; break ;
2017-07-07 19:25:47 +00:00
default : $f = $outFormat ; break ;
2017-05-21 21:16:32 +00:00
}
2017-07-07 19:25:47 +00:00
return $date -> format ( $f );
2017-05-21 21:16:32 +00:00
}
2017-08-29 14:50:31 +00:00
public static function normalize ( $date , string $inFormat = null , bool $inLocal = false ) {
if ( $date instanceof \DateTimeInterface ) {
2017-07-07 19:25:47 +00:00
return $date ;
2017-08-29 14:50:31 +00:00
} elseif ( is_numeric ( $date )) {
2017-05-21 21:16:32 +00:00
$time = ( int ) $date ;
2017-08-29 14:50:31 +00:00
} elseif ( $date === null ) {
2017-05-21 21:16:32 +00:00
return null ;
2017-08-29 14:50:31 +00:00
} elseif ( is_string ( $date )) {
2017-07-05 13:09:38 +00:00
try {
2017-07-07 19:25:47 +00:00
$tz = ( ! $inLocal ) ? new \DateTimeZone ( " UTC " ) : null ;
2017-08-29 14:50:31 +00:00
if ( ! is_null ( $inFormat )) {
switch ( $inFormat ) {
2017-07-07 19:25:47 +00:00
case 'http' : $f = " D, d M Y H:i:s \ G \ M \T " ; break ;
2017-10-19 19:18:58 +00:00
case 'iso8601' : $f = " Y-m-d \T H:i:sP " ; break ;
2017-07-07 19:25:47 +00:00
case 'sql' : $f = " Y-m-d H:i:s " ; break ;
case 'date' : $f = " Y-m-d " ; break ;
case 'time' : $f = " H:i:s " ; break ;
default : $f = $inFormat ; break ;
}
return \DateTime :: createFromFormat ( " ! " . $f , $date , $tz );
} else {
return new \DateTime ( $date , $tz );
}
2017-08-29 14:50:31 +00:00
} catch ( \Throwable $e ) {
2017-07-05 13:09:38 +00:00
return null ;
}
2017-08-29 14:50:31 +00:00
} elseif ( is_bool ( $date )) {
2017-05-21 21:16:32 +00:00
return null ;
} else {
$time = ( int ) $date ;
}
2017-07-15 17:33:17 +00:00
$tz = ( ! $inLocal ) ? new \DateTimeZone ( " UTC " ) : null ;
$d = new \DateTime ( " now " , $tz );
2017-07-07 19:25:47 +00:00
$d -> setTimestamp ( $time );
return $d ;
2017-05-21 21:16:32 +00:00
}
2017-08-18 02:36:15 +00:00
2017-08-29 14:50:31 +00:00
public static function add ( string $interval , $date = null ) : \DateTimeInterface {
2017-08-18 02:36:15 +00:00
return self :: modify ( " add " , $interval , $date );
}
2017-08-29 14:50:31 +00:00
public static function sub ( string $interval , $date = null ) : \DateTimeInterface {
2017-08-18 02:36:15 +00:00
return self :: modify ( " sub " , $interval , $date );
}
2017-08-29 14:50:31 +00:00
protected static function modify ( string $func , string $interval , $date = null ) : \DateTimeInterface {
2017-08-18 02:36:15 +00:00
$date = self :: normalize ( $date ? ? time ());
2017-08-29 14:50:31 +00:00
if ( $date instanceof \DateTimeImmutable ) {
2017-08-18 02:36:15 +00:00
return $date -> $func ( new \DateInterval ( $interval ));
} else {
$date -> $func ( new \DateInterval ( $interval ));
return $date ;
}
}
2017-08-29 14:50:31 +00:00
}