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 DateTimeInterface;
14
15/**
16 * Represents a Generalized Time type.
17 *
18 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
19 */
20class GeneralizedTimeType extends AbstractTimeType
21{
22    /**
23     * GeneralizedTime defined as:
24     *
25     * a)  A string representing the calendar date, as specified in ISO 8601, with a four-digit representation of the
26     *     year, a two-digit representation of the month and a two-digit representation of the day, without use of
27     *     separators, followed by a string representing the time of day, as specified in ISO 8601, without separators
28     *     other than decimal comma or decimal period (as provided for in ISO 8601), and with no terminating Z (as
29     *     provided for in ISO 8601); or
30     *
31     * b)  the characters in a) above followed by an upper-case letter Z; or
32     *
33     * c)  the characters in a) above followed by a string representing a local time differential, as specified in
34     *     ISO 8601, without separators
35     */
36    public const TIME_REGEX = '~^
37        (\d\d\d\d)              # 1  - Year
38        (\d\d)                  # 2  - Month
39        (\d\d)                  # 3  - Day
40        (\d\d)                  # 4  - Hour
41        ((\d\d)                 # 6  - Minutes, capture group before since all others are optional
42            ((\d\d)             # 8  - Seconds, capture group as this can be optional
43                ((\.\d{1,}))?   # 10 - Fractions of seconds, also optional.
44            )?                  # ---- End of seconds capture group.
45        )?                      # ---- End of minutes capture group.
46        (Z|[\+\-]\d\d\d\d)?     # 11 - Timezone modifier (optional). It can either be a Z (UTC) or a time differential.
47    $~x';
48
49    public const REGEX_MAP = [
50        'hours' => 4,
51        'minutes' => 6,
52        'seconds' => 8,
53        'fractions' => 10,
54        'timezone' => 11,
55    ];
56
57    protected $tagNumber = self::TAG_TYPE_GENERALIZED_TIME;
58
59    /**
60     * Valid datetime formats.
61     */
62    protected $validDateFormats = [
63        self::FORMAT_HOURS,
64        self::FORMAT_MINUTES,
65        self::FORMAT_SECONDS,
66        self::FORMAT_FRACTIONS,
67    ];
68
69    /**
70     * Valid timezone formats
71     */
72    protected $validTzFormats = [
73        self::TZ_UTC,
74        self::TZ_DIFF,
75        self::TZ_LOCAL,
76    ];
77
78    /**
79     * {@inheritdoc}
80     */
81    public function __construct(?DateTimeInterface $dateTime = null, string $dateFormat = self::FORMAT_FRACTIONS, string $tzFormat = self::TZ_UTC)
82    {
83        parent::__construct($dateTime, $dateFormat, $tzFormat);
84    }
85}
86