Completed
Push — issue/134 ( d0dc5e...07c20b )
by Alex
01:47
created

DateTimeBuilder::convertToDateTime()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 1
crap 3
1
<?php
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 71
    public function __construct(LoggerInterface $logger = null)
62
    {
63 71
        if (is_null($logger)) {
64 61
            $logger = new NullLogger;
65 61
        }
66 71
        $this->logger = $logger;
67 71
        $this->setTimezone(new \DateTimeZone(date_default_timezone_get()));
68 71
    }
69
70
    /**
71
     * @param $dateFormat
72
     * @return $this
73
     */
74 23
    public function addDateFormat($dateFormat)
75
    {
76 23
        $this->dateFormats[] = $dateFormat;
77
78 23
        return $this;
79
    }
80
81
    /**
82
     * @param  array $dateFormats
83
     * @return $this
84
     */
85 3
    public function setDateFormats(array $dateFormats)
86
    {
87 3
        $this->dateFormats = $dateFormats;
88
89 3
        return $this;
90
    }
91
92
    /**
93
     * @return string
94
     */
95 11
    public function getLastGuessedFormat()
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|false             date Format
104
     * @throws InvalidArgumentException
105
     */
106 13
    public function guessDateFormat($date)
107
    {
108 13
        foreach ($this->dateFormats as $format) {
109 13
            $test = \DateTime::createFromFormat($format, $date);
110 13
            if ($test instanceof \DateTime) {
111 11
                $this->lastGuessedFormat = $format;
112
113 11
                return $format;
114
            }
115 9
        }
116
117 2
        return false;
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 11
    public function convertToDateTime($string)
126
    {
127 11
        $string = trim($string);
128 11
        foreach ([$this->getLastGuessedFormat(), $this->guessDateFormat($string) ] as $format) {
129 11
            $date = $this->newDate($format, $string);
130 11
            if ($date instanceof \DateTime) {
131 10
                $date->setTimezone($this->getTimezone());
132
133 10
                return $date;
134
            }
135 8
        }
136
137 1
        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 2
    public function stringToDateTime($string)
147
    {
148 2
        $this->logger->notice("unsupported date format, use strtotime() to build the DateTime instance : {$string}");
149
150 2
        if (false === strtotime($string)) {
151 1
            throw new \InvalidArgumentException('Impossible to convert date : '.$string);
152
        }
153 1
        $date = new \DateTime($string, $this->getFeedTimezone());
154 1
        $date->setTimezone($this->getTimezone());
155
156 1
        return $date;
157
    }
158
159
    /**
160
     * @return \DateTimeZone
161
     */
162 12
    public function getFeedTimezone()
163
    {
164 12
        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)
173
    {
174
        $this->feedTimezone = $timezone;
175
    }
176
177
    /**
178
     * Resets feedTimezone to null.
179
     */
180
    public function resetFeedTimezone()
181
    {
182
        $this->feedTimezone = null;
183
    }
184
185
    /**
186
     * @return \DateTimeZone
187
     */
188 12
    public function getServerTimezone()
189
    {
190 12
        return $this->serverTimezone;
191
    }
192
193
    /**
194
     * @param \DateTimeZone $timezone
195
     */
196 71
    public function setServerTimezone(\DateTimeZone $timezone)
197
    {
198 71
        $this->serverTimezone = $timezone;
199 71
    }
200
201
    /**
202
     * @return \DateTimeZone
203
     */
204 12
    public function getTimezone()
205
    {
206 12
        return $this->getServerTimezone();
207
    }
208
209
    /**
210
     * @param \DateTimeZone $timezone
211
     */
212 71
    public function setTimezone(\DateTimeZone $timezone)
213
    {
214 71
        $this->setServerTimezone($timezone);
215 71
    }
216
217
218
    /**
219
     * @param $format
220
     * @param $string
221
     * @return \DateTime
222
     */
223 11
    protected function newDate($format, $string)
224
    {
225 11
        if (!! $this->getFeedTimezone()) {
226
            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 226 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...
227
        }
228
229 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 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