Completed
Pull Request — master (#230)
by
unknown
02:43 queued 01:26
created

DateTimeBuilder::convertToDateTime()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

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