Time   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 4
dl 0
loc 103
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A fromASN1() 0 6 1
A fromString() 0 4 1
A dateTime() 0 4 1
A toASN1() 0 18 4
A _determineType() 0 7 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace X509\Certificate;
6
7
use ASN1\Element;
8
use ASN1\Type\TimeType;
9
use ASN1\Type\Primitive\GeneralizedTime;
10
use ASN1\Type\Primitive\UTCTime;
11
use X509\Feature\DateTimeHelper;
12
13
/**
14
 * Implements <i>Time</i> ASN.1 type.
15
 *
16
 * @link https://tools.ietf.org/html/rfc5280#section-4.1
17
 */
18
class Time
19
{
20
    use DateTimeHelper;
21
    
22
    /**
23
     * Datetime.
24
     *
25
     * @var \DateTimeImmutable $_dt
26
     */
27
    protected $_dt;
28
    
29
    /**
30
     * Time ASN.1 type tag.
31
     *
32
     * @var int $_type
33
     */
34
    protected $_type;
35
    
36
    /**
37
     * Constructor.
38
     *
39
     * @param \DateTimeImmutable $dt
40
     */
41 35
    public function __construct(\DateTimeImmutable $dt)
42
    {
43 35
        $this->_dt = $dt;
44 35
        $this->_type = self::_determineType($dt);
45 35
    }
46
    
47
    /**
48
     * Initialize from ASN.1.
49
     *
50
     * @param TimeType $el
51
     * @return self
52
     */
53 23
    public static function fromASN1(TimeType $el): self
54
    {
55 23
        $obj = new self($el->dateTime());
56 23
        $obj->_type = $el->tag();
57 23
        return $obj;
58
    }
59
    
60
    /**
61
     * Initialize from date string.
62
     *
63
     * @param string|null $time
64
     * @param string|null $tz
65
     * @return self
66
     */
67 13
    public static function fromString($time, $tz = null): self
68
    {
69 13
        return new self(self::_createDateTime($time, $tz));
70
    }
71
    
72
    /**
73
     * Get datetime.
74
     *
75
     * @return \DateTimeImmutable
76
     */
77 50
    public function dateTime(): \DateTimeImmutable
78
    {
79 50
        return $this->_dt;
80
    }
81
    
82
    /**
83
     * Generate ASN.1.
84
     *
85
     * @throws \UnexpectedValueException
86
     * @return TimeType
87
     */
88 70
    public function toASN1(): TimeType
89
    {
90 70
        $dt = $this->_dt;
91 70
        switch ($this->_type) {
92 70
            case Element::TYPE_UTC_TIME:
93 67
                return new UTCTime($dt);
94 3
            case Element::TYPE_GENERALIZED_TIME:
95
                // GeneralizedTime must not contain fractional seconds
96
                // (rfc5280 4.1.2.5.2)
97 2
                if ($dt->format("u") != 0) {
98
                    // remove fractional seconds (round down)
99 1
                    $dt = self::_roundDownFractionalSeconds($dt);
100
                }
101 2
                return new GeneralizedTime($dt);
102
        }
103 1
        throw new \UnexpectedValueException(
104 1
            "Time type " . Element::tagToName($this->_type) . " not supported.");
105
    }
106
    
107
    /**
108
     * Determine whether to use UTCTime or GeneralizedTime ASN.1 type.
109
     *
110
     * @param \DateTimeImmutable $dt
111
     * @return int Type tag
112
     */
113 35
    protected static function _determineType(\DateTimeImmutable $dt): int
114
    {
115 35
        if ($dt->format("Y") >= 2050) {
116 3
            return Element::TYPE_GENERALIZED_TIME;
117
        }
118 32
        return Element::TYPE_UTC_TIME;
119
    }
120
}
121