Completed
Push — master ( 4c7da2...64af60 )
by Alex
02:34 queued 46s
created

DateTimeBuilder   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 215
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 215
ccs 51
cts 58
cp 0.8793
rs 10
c 0
b 0
f 0

15 Methods

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