DateTimeBuilder   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 87.93%

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 2
dl 0
loc 219
ccs 51
cts 58
cp 0.8793
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A addDateFormat() 0 6 1
A setDateFormats() 0 6 1
A getLastGuessedFormat() 0 4 1
A guessDateFormat() 0 13 3
A convertToDateTime() 0 14 3
A stringToDateTime() 0 12 2
A getFeedTimezone() 0 4 1
A setFeedTimezone() 0 4 1
A resetFeedTimezone() 0 4 1
A getServerTimezone() 0 4 1
A setServerTimezone() 0 4 1
A getTimezone() 0 4 1
A setTimezone() 0 4 1
A newDate() 0 8 2
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of the feed-io package.
4
 *
5
 * (c) Alexandre Debril <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace FeedIo\Rule;
12
13
use Psr\Log\LoggerInterface;
14
use Psr\Log\NullLogger;
15
16
class DateTimeBuilder implements DateTimeBuilderInterface
17
{
18
    /**
19
     * Supported date formats
20
     * @var array
21
     */
22
    protected $dateFormats = [
23
        \DateTime::RFC2822,
24
        \DateTime::ATOM,
25
        \DateTime::RFC3339,
26
        \DateTime::RFC3339_EXTENDED,
27
        \DateTime::RSS,
28
        \DateTime::W3C,
29
        'Y-m-d\TH:i:s.uP',
30
        'Y-m-d\TH:i:s.uvP',
31
        'Y-m-d\TH:i:s',
32
        'Y-m-d',
33
        'd/m/Y',
34
        'D, d M Y H:i O',
35
        'D, d M Y H:i:s O',
36
        'D M d Y H:i:s e',
37
        '*, m#d#Y - H:i',
38
        'D, d M Y H:i:s \U\T',
39
        '*, d M* Y H:i:s e',
40
        '*, d M Y',
41
    ];
42
43
    /**
44
     * @var \DateTimeZone
45
     */
46
    protected $feedTimezone;
47
48
    /**
49
     * @var \DateTimeZone
50
     */
51
    protected $serverTimezone;
52
53
    /**
54
     * @var LoggerInterface
55
     */
56
    protected $logger;
57
58
    /**
59
     * @var string
60
     */
61
    protected $lastGuessedFormat = \DateTime::RFC2822;
62
63
    /**
64
     * @param \Psr\Log\LoggerInterface        $logger
65
     */
66 78
    public function __construct(LoggerInterface $logger = null)
67
    {
68 78
        if (is_null($logger)) {
69 65
            $logger = new NullLogger;
70
        }
71 78
        $this->logger = $logger;
72 78
        $this->setTimezone(new \DateTimeZone(date_default_timezone_get()));
73 78
    }
74
75
    /**
76
     * @param $dateFormat
77
     * @return DateTimeBuilder
78
     */
79 22
    public function addDateFormat(string $dateFormat) : DateTimeBuilderInterface
80
    {
81 22
        $this->dateFormats[] = $dateFormat;
82
83 22
        return $this;
84
    }
85
86
    /**
87
     * @param  array $dateFormats
88
     * @return $this
89
     */
90 2
    public function setDateFormats(array $dateFormats) : DateTimeBuilderInterface
91
    {
92 2
        $this->dateFormats = $dateFormats;
93
94 2
        return $this;
95
    }
96
97
    /**
98
     * @return string
99
     */
100 15
    public function getLastGuessedFormat() : string
101
    {
102 15
        return $this->lastGuessedFormat;
103
    }
104
105
    /**
106
     * Tries to guess the date's format from the list
107
     * @param  string                   $date
108
     * @return string|null             date Format
109
     */
110 17
    public function guessDateFormat(string $date) : ? string
111
    {
112 17
        foreach ($this->dateFormats as $format) {
113 17
            $test = \DateTime::createFromFormat($format, $date);
114 17
            if ($test instanceof \DateTime) {
115 15
                $this->lastGuessedFormat = $format;
116
117 15
                return $format;
118
            }
119
        }
120
121 2
        return null;
122
    }
123
124
    /**
125
     * Creates a DateTime instance for the given string. Default format is RFC2822
126
     * @param  string                   $string
127
     * @return \DateTime
128
     */
129 15
    public function convertToDateTime(string $string) : \DateTime
130
    {
131 15
        $string = trim($string);
132 15
        foreach ([$this->getLastGuessedFormat(), $this->guessDateFormat($string) ] as $format) {
133 15
            $date = $this->newDate((string) $format, $string);
134 15
            if ($date instanceof \DateTime) {
135 14
                $date->setTimezone($this->getTimezone());
136
137 14
                return $date;
138
            }
139
        }
140
141 1
        return $this->stringToDateTime($string);
142
    }
143
144
    /**
145
     * Creates a DateTime instance for the given string if the format was not catch from the list
146
     * @param  string                   $string
147
     * @return \DateTime
148
     * @throws InvalidArgumentException
149
     */
150 2
    public function stringToDateTime(string $string) : \DateTime
151
    {
152 2
        $this->logger->notice("unsupported date format, use strtotime() to build the DateTime instance : {$string}");
153
154 2
        if (false === strtotime($string)) {
155 1
            throw new \InvalidArgumentException('Impossible to convert date : '.$string);
156
        }
157 1
        $date = new \DateTime($string, $this->getFeedTimezone());
158 1
        $date->setTimezone($this->getTimezone());
159
160 1
        return $date;
161
    }
162
163
    /**
164
     * @return \DateTimeZone
165
     */
166 16
    public function getFeedTimezone() : ? \DateTimeZone
167
    {
168 16
        return $this->feedTimezone;
169
    }
170
171
    /**
172
     * Specifies the feed's timezone. Do this it the timezone is missing
173
     *
174
     * @param \DateTimeZone $timezone
175
     */
176
    public function setFeedTimezone(\DateTimeZone $timezone) : void
177
    {
178
        $this->feedTimezone = $timezone;
179
    }
180
181
    /**
182
     * Resets feedTimezone to null.
183
     */
184
    public function resetFeedTimezone() : void
185
    {
186
        $this->feedTimezone = null;
187
    }
188
189
    /**
190
     * @return \DateTimeZone
191
     */
192 16
    public function getServerTimezone() : ? \DateTimeZone
193
    {
194 16
        return $this->serverTimezone;
195
    }
196
197
    /**
198
     * @param \DateTimeZone $timezone
199
     */
200 78
    public function setServerTimezone(\DateTimeZone $timezone) : void
201
    {
202 78
        $this->serverTimezone = $timezone;
203 78
    }
204
205
    /**
206
     * @return \DateTimeZone
207
     */
208 16
    public function getTimezone() : ? \DateTimeZone
209
    {
210 16
        return $this->getServerTimezone();
211
    }
212
213
    /**
214
     * @param \DateTimeZone $timezone
215
     */
216 78
    public function setTimezone(\DateTimeZone $timezone) : void
217
    {
218 78
        $this->setServerTimezone($timezone);
219 78
    }
220
221
    /**
222
     * @param $format
223
     * @param $string
224
     * @return \DateTime
225
     */
226 15
    protected function newDate(string $format, string $string)
227
    {
228 15
        if (!! $this->getFeedTimezone()) {
229
            return \DateTime::createFromFormat($format, $string, $this->getFeedTimezone());
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...is->getFeedTimezone()); of type DateTime|false adds false to the return on line 229 which is incompatible with the return type documented by FeedIo\Rule\DateTimeBuilder::newDate of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
230
        }
231
232 15
        return \DateTime::createFromFormat($format, $string);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFormat($format, $string); of type DateTime|false adds false to the return on line 232 which is incompatible with the return type documented by FeedIo\Rule\DateTimeBuilder::newDate of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
233
    }
234
}
235