Completed
Pull Request — master (#274)
by Alex
01:56
created

DateTimeBuilder::getTimezone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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