1<?php 2/** 3 * This file is part of the FreeDSx ASN1 package. 4 * 5 * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11namespace FreeDSx\Asn1\Type; 12 13use DateTime; 14use DateTimeInterface; 15use FreeDSx\Asn1\Exception\InvalidArgumentException; 16 17/** 18 * Generalized / UTC time type. 19 * 20 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 21 */ 22class AbstractTimeType extends AbstractType 23{ 24 /** 25 * Format the date time to the minutes. 26 */ 27 public const FORMAT_HOURS = 'hours'; 28 29 /** 30 * Format the date time to the minutes. 31 */ 32 public const FORMAT_MINUTES = 'minutes'; 33 34 /** 35 * Format the date time to the seconds. 36 */ 37 public const FORMAT_SECONDS = 'seconds'; 38 39 /** 40 * Format the datetime to the fractional seconds if possible (empty fractionals not allowed), otherwise to the seconds. 41 */ 42 public const FORMAT_FRACTIONS = 'fractions'; 43 44 /** 45 * Use local time (ie. no ending timezone specification) 46 */ 47 public const TZ_LOCAL = 'local'; 48 49 /** 50 * Use a UTC timezone (ie. end with a Z) 51 */ 52 public const TZ_UTC = 'utc'; 53 54 /** 55 * Use a timezone differential (ie. -0500) 56 */ 57 public const TZ_DIFF = 'diff'; 58 59 /** 60 * @var string[] Valid datetime formats. 61 */ 62 protected $validDateFormats = []; 63 64 /** 65 * @var string[] Valid timezone formats 66 */ 67 protected $validTzFormats = []; 68 69 /** 70 * @var string 71 */ 72 protected $tzFormat; 73 74 /** 75 * @var string 76 */ 77 protected $dateFormat; 78 79 /** 80 * @var DateTimeInterface|null 81 */ 82 protected $value; 83 84 /** 85 * @param DateTimeInterface|null $dateTime 86 * @param string $dateFormat Represents the furthest datetime element to represent in the datetime object. 87 * @param string $tzFormat Represents the format of the timezone. 88 */ 89 public function __construct(?DateTimeInterface $dateTime, string $dateFormat, string $tzFormat) 90 { 91 $this->setDateTimeFormat($dateFormat); 92 $this->setTimeZoneFormat($tzFormat); 93 parent::__construct($dateTime ?? new DateTime()); 94 } 95 96 /** 97 * @param DateTimeInterface $dateTime 98 * @return $this 99 */ 100 public function setValue(DateTimeInterface $dateTime) 101 { 102 $this->value = $dateTime; 103 104 return $this; 105 } 106 107 /** 108 * @return DateTimeInterface 109 */ 110 public function getValue(): DateTimeInterface 111 { 112 return $this->value; 113 } 114 115 /** 116 * @return string 117 */ 118 public function getTimeZoneFormat(): string 119 { 120 return $this->tzFormat; 121 } 122 123 /** 124 * @param string $tzFormat 125 * @return $this 126 */ 127 public function setTimeZoneFormat(string $tzFormat) 128 { 129 if (!in_array($tzFormat, $this->validTzFormats)) { 130 throw new InvalidArgumentException(sprintf( 131 'The timezone format %s is not valid. It must be one of: %s', 132 $tzFormat, 133 implode(', ', $this->validTzFormats) 134 )); 135 } 136 $this->tzFormat = $tzFormat; 137 138 return $this; 139 } 140 141 /** 142 * @return string 143 */ 144 public function getDateTimeFormat(): string 145 { 146 return $this->dateFormat; 147 } 148 149 /** 150 * @param string $dateFormat 151 * @return $this 152 */ 153 public function setDateTimeFormat(string $dateFormat) 154 { 155 if (!in_array($dateFormat, $this->validDateFormats)) { 156 throw new InvalidArgumentException(sprintf( 157 'The datetime format %s is not valid. It must be one of: %s', 158 $dateFormat, 159 implode(', ', $this->validDateFormats) 160 )); 161 } 162 $this->dateFormat = $dateFormat; 163 164 return $this; 165 } 166 167 /** 168 * @param string|int $tagNumber 169 * @param int $class 170 * @param bool $isConstructed 171 * @param DateTimeInterface|null $dateTime 172 * @param string $dateFormat 173 * @param string $tzFormat 174 * @return AbstractTimeType 175 */ 176 public static function withTag($tagNumber, int $class, bool $isConstructed, ?DateTimeInterface $dateTime, string $dateFormat, string $tzFormat) 177 { 178 $type = new static($dateTime, $dateFormat, $tzFormat); 179 $type->tagNumber = $tagNumber; 180 $type->taggingClass = $class; 181 $type->isConstructed = $isConstructed; 182 183 return $type; 184 } 185} 186