Date   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 4
dl 0
loc 162
ccs 17
cts 17
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A fromString() 0 11 2
A equals() 0 9 4
A __toString() 0 4 1
A getYear() 0 4 1
A getMonth() 0 4 1
A getDay() 0 4 1
A asDateTime() 0 4 1
A getDaysInMonth() 0 4 1
A fromDateTime() 0 10 1
A __construct() 0 21 3
1
<?php
2
/**
3
 * Copyright 2016 Alexandru Guzinschi <[email protected]>.
4
 *
5
 * This software may be modified and distributed under the terms
6
 * of the MIT license. See the LICENSE file for details.
7
 */
8
namespace Gentle\Embeddable;
9
10
use Gentle\Embeddable\Date\Day;
11
use Gentle\Embeddable\Date\Month;
12
use Gentle\Embeddable\Date\Year;
13
14
/**
15
 * @author Alexandru Guzinschi <[email protected]>
16
 */
17
final class Date extends Embeddable
18
{
19
    /** @var Year */
20
    private $year;
21
22
    /** @var Month */
23
    private $month;
24
25
    /** @var Day */
26
    private $day;
27
28
    /** @var \DateTime */
29
    private $dateTime;
30
31
    /**
32
     * @static
33
     * @access public
34
     * @param  \DateTime $birthday
35
     * @return Date
36
     *
37
     * @throws \InvalidArgumentException
38
     * @throws \OutOfRangeException
39
     * @throws \DomainException
40
     * @throws \LengthException
41
     */
42 6
    public static function fromDateTime(\DateTime $birthday)
43
    {
44 6
        $date = clone $birthday;
45
46 6
        return new self(
47 6
            new Year($date->format('Y')),
48 6
            new Month($date->format('m')),
49 6
            new Day($date->format('d'))
50
        );
51
    }
52
53
    /**
54
     * @static
55
     * @access public
56
     * @param string $date
57
     * @param string $format
58
     * @return Date
59
     *
60
     * @throws \InvalidArgumentException
61
     * @throws \OutOfRangeException
62
     * @throws \DomainException
63
     * @throws \LengthException
64
     */
65 1
    public static function fromString($date, $format = \DateTime::ATOM)
66
    {
67 1
        $dateTime = \DateTime::createFromFormat($format, $date);
68
69 1
        $err = \DateTime::getLastErrors();
70 1
        if ($err['error_count'] > 0) {
71 1
            throw new \InvalidArgumentException(sprintf('%s', implode(', ', $err['errors'])));
72
        }
73
74 1
        return self::fromDateTime($dateTime);
75
    }
76
77
    /**
78
     * @param Year $year
79
     * @param Month $month
80
     * @param Day $day
81
     *
82
     * @throws \OutOfRangeException
83
     * @throws \DomainException
84
     */
85 23
    public function __construct(Year $year, Month $month, Day $day)
86
    {
87 23
        if ((int)sprintf('%s', $day) > ($daysNo = $this->getDaysInMonth($month, $year))) {
88 2
            throw new \OutOfRangeException(
89 2
                sprintf('Month %s of %s has only %d days.', $month, $year, $daysNo)
90
            );
91
        }
92
93 21
        $this->dateTime = \DateTime::createFromFormat('Y-m-d', sprintf('%s-%s-%s', $year, $month, $day));
94
95
        // @codeCoverageIgnoreStart
96
        $err = \DateTime::getLastErrors();
97
        if ($err['error_count'] > 0) {
98
            throw new \DomainException(sprintf('%s', implode(', ', $err['errors'])));
99
        }
100
        // @codeCoverageIgnoreStop
101
102
        $this->year = $year;
103
        $this->month = $month;
104
        $this->day = $day;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110
    public function equals(Embeddable $object)
111
    {
112
        /* @var Date $object */
113
        return get_class($object) === 'Gentle\Embeddable\Date' &&
114
            (string)$this->year === (string)$object->getYear() &&
115
            (string)$this->month === (string)$object->getMonth() &&
116
            (string)$this->day === (string)$object->getDay()
117
        ;
118
    }
119
120
    /**
121
     * Returned format is `Y-m-d`.
122
     *
123
     * {@inheritdoc}
124
     */
125
    public function __toString()
126
    {
127
        return sprintf('%s-%s-%s', $this->getYear(), $this->getMonth(), $this->getDay());
128
    }
129
130
    /**
131
     * @access public
132
     * @return Year
133
     */
134
    public function getYear()
135
    {
136
        return $this->year;
137
    }
138
139
    /**
140
     * @access public
141
     * @return Month
142
     */
143
    public function getMonth()
144
    {
145
        return $this->month;
146
    }
147
148
    /**
149
     * @access public
150
     * @return Day
151
     */
152
    public function getDay()
153
    {
154
        return $this->day;
155
    }
156
157
    /**
158
     * @access public
159
     * @return \DateTime
160
     */
161
    public function asDateTime()
162
    {
163
        return $this->dateTime;
164
    }
165
166
    /**
167
     * Get number of days in specified month.
168
     *
169
     * @access private
170
     * @param  Month $month
171
     * @param  Year  $year
172
     * @return int
173
     */
174
    private function getDaysInMonth(Month $month, Year $year)
175
    {
176
        return (int)date('t', mktime(0, 0, 0, (string)$month, 1, (string)$year));
177
    }
178
}
179