Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the Carbon package.
5
 *
6
 * (c) Brian Nesbitt <brian@nesbot.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Carbon;
13
 
14
use Carbon\Exceptions\InvalidCastException;
15
use Carbon\Exceptions\InvalidTimeZoneException;
16
use DateTimeInterface;
17
use DateTimeZone;
18
use Throwable;
19
 
20
class CarbonTimeZone extends DateTimeZone
21
{
22
    public function __construct($timezone = null)
23
    {
24
        parent::__construct(static::getDateTimeZoneNameFromMixed($timezone));
25
    }
26
 
27
    protected static function parseNumericTimezone($timezone)
28
    {
29
        if ($timezone <= -100 || $timezone >= 100) {
30
            throw new InvalidTimeZoneException('Absolute timezone offset cannot be greater than 100.');
31
        }
32
 
33
        return ($timezone >= 0 ? '+' : '').ltrim($timezone, '+').':00';
34
    }
35
 
36
    protected static function getDateTimeZoneNameFromMixed($timezone)
37
    {
38
        if ($timezone === null) {
39
            return date_default_timezone_get();
40
        }
41
 
42
        if (\is_string($timezone)) {
43
            $timezone = preg_replace('/^\s*([+-]\d+)(\d{2})\s*$/', '$1:$2', $timezone);
44
        }
45
 
46
        if (is_numeric($timezone)) {
47
            return static::parseNumericTimezone($timezone);
48
        }
49
 
50
        return $timezone;
51
    }
52
 
53
    protected static function getDateTimeZoneFromName(&$name)
54
    {
55
        return @timezone_open($name = (string) static::getDateTimeZoneNameFromMixed($name));
56
    }
57
 
58
    /**
59
     * Cast the current instance into the given class.
60
     *
61
     * @param string $className The $className::instance() method will be called to cast the current object.
62
     *
63
     * @return DateTimeZone
64
     */
65
    public function cast(string $className)
66
    {
67
        if (!method_exists($className, 'instance')) {
68
            if (is_a($className, DateTimeZone::class, true)) {
69
                return new $className($this->getName());
70
            }
71
 
72
            throw new InvalidCastException("$className has not the instance() method needed to cast the date.");
73
        }
74
 
75
        return $className::instance($this);
76
    }
77
 
78
    /**
79
     * Create a CarbonTimeZone from mixed input.
80
     *
81
     * @param DateTimeZone|string|int|null $object     original value to get CarbonTimeZone from it.
82
     * @param DateTimeZone|string|int|null $objectDump dump of the object for error messages.
83
     *
84
     * @throws InvalidTimeZoneException
85
     *
86
     * @return false|static
87
     */
88
    public static function instance($object = null, $objectDump = null)
89
    {
90
        $tz = $object;
91
 
92
        if ($tz instanceof static) {
93
            return $tz;
94
        }
95
 
96
        if ($tz === null) {
97
            return new static();
98
        }
99
 
100
        if (!$tz instanceof DateTimeZone) {
101
            $tz = static::getDateTimeZoneFromName($object);
102
        }
103
 
104
        if ($tz !== false) {
105
            return new static($tz->getName());
106
        }
107
 
108
        if (Carbon::isStrictModeEnabled()) {
109
            throw new InvalidTimeZoneException('Unknown or bad timezone ('.($objectDump ?: $object).')');
110
        }
111
 
112
        return false;
113
    }
114
 
115
    /**
116
     * Returns abbreviated name of the current timezone according to DST setting.
117
     *
118
     * @param bool $dst
119
     *
120
     * @return string
121
     */
122
    public function getAbbreviatedName($dst = false)
123
    {
124
        $name = $this->getName();
125
 
126
        foreach ($this->listAbbreviations() as $abbreviation => $zones) {
127
            foreach ($zones as $zone) {
128
                if ($zone['timezone_id'] === $name && $zone['dst'] == $dst) {
129
                    return $abbreviation;
130
                }
131
            }
132
        }
133
 
134
        return 'unknown';
135
    }
136
 
137
    /**
138
     * @alias getAbbreviatedName
139
     *
140
     * Returns abbreviated name of the current timezone according to DST setting.
141
     *
142
     * @param bool $dst
143
     *
144
     * @return string
145
     */
146
    public function getAbbr($dst = false)
147
    {
148
        return $this->getAbbreviatedName($dst);
149
    }
150
 
151
    /**
152
     * Get the offset as string "sHH:MM" (such as "+00:00" or "-12:30").
153
     *
154
     * @param DateTimeInterface|null $date
155
     *
156
     * @return string
157
     */
158
    public function toOffsetName(DateTimeInterface $date = null)
159
    {
160
        return static::getOffsetNameFromMinuteOffset(
161
            $this->getOffset($date ?: Carbon::now($this)) / 60
162
        );
163
    }
164
 
165
    /**
166
     * Returns a new CarbonTimeZone object using the offset string instead of region string.
167
     *
168
     * @param DateTimeInterface|null $date
169
     *
170
     * @return CarbonTimeZone
171
     */
172
    public function toOffsetTimeZone(DateTimeInterface $date = null)
173
    {
174
        return new static($this->toOffsetName($date));
175
    }
176
 
177
    /**
178
     * Returns the first region string (such as "America/Toronto") that matches the current timezone or
179
     * false if no match is found.
180
     *
181
     * @see timezone_name_from_abbr native PHP function.
182
     *
183
     * @param DateTimeInterface|null $date
184
     * @param int                    $isDst
185
     *
186
     * @return string|false
187
     */
188
    public function toRegionName(DateTimeInterface $date = null, $isDst = 1)
189
    {
190
        $name = $this->getName();
191
        $firstChar = substr($name, 0, 1);
192
 
193
        if ($firstChar !== '+' && $firstChar !== '-') {
194
            return $name;
195
        }
196
 
197
        $date = $date ?: Carbon::now($this);
198
 
199
        // Integer construction no longer supported since PHP 8
200
        // @codeCoverageIgnoreStart
201
        try {
202
            $offset = @$this->getOffset($date) ?: 0;
203
        } catch (Throwable $e) {
204
            $offset = 0;
205
        }
206
        // @codeCoverageIgnoreEnd
207
 
208
        $name = @timezone_name_from_abbr('', $offset, $isDst);
209
 
210
        if ($name) {
211
            return $name;
212
        }
213
 
214
        foreach (timezone_identifiers_list() as $timezone) {
215
            if (Carbon::instance($date)->tz($timezone)->getOffset() === $offset) {
216
                return $timezone;
217
            }
218
        }
219
 
220
        return false;
221
    }
222
 
223
    /**
224
     * Returns a new CarbonTimeZone object using the region string instead of offset string.
225
     *
226
     * @param DateTimeInterface|null $date
227
     *
228
     * @return CarbonTimeZone|false
229
     */
230
    public function toRegionTimeZone(DateTimeInterface $date = null)
231
    {
232
        $tz = $this->toRegionName($date);
233
 
234
        if ($tz !== false) {
235
            return new static($tz);
236
        }
237
 
238
        if (Carbon::isStrictModeEnabled()) {
239
            throw new InvalidTimeZoneException('Unknown timezone for offset '.$this->getOffset($date ?: Carbon::now($this)).' seconds.');
240
        }
241
 
242
        return false;
243
    }
244
 
245
    /**
246
     * Cast to string (get timezone name).
247
     *
248
     * @return string
249
     */
250
    public function __toString()
251
    {
252
        return $this->getName();
253
    }
254
 
255
    /**
256
     * Return the type number:
257
     *
258
     * Type 1; A UTC offset, such as -0300
259
     * Type 2; A timezone abbreviation, such as GMT
260
     * Type 3: A timezone identifier, such as Europe/London
261
     */
262
    public function getType(): int
263
    {
264
        return preg_match('/"timezone_type";i:(\d)/', serialize($this), $match) ? (int) $match[1] : 3;
265
    }
266
 
267
    /**
268
     * Create a CarbonTimeZone from mixed input.
269
     *
270
     * @param DateTimeZone|string|int|null $object
271
     *
272
     * @return false|static
273
     */
274
    public static function create($object = null)
275
    {
276
        return static::instance($object);
277
    }
278
 
279
    /**
280
     * Create a CarbonTimeZone from int/float hour offset.
281
     *
282
     * @param float $hourOffset number of hour of the timezone shift (can be decimal).
283
     *
284
     * @return false|static
285
     */
286
    public static function createFromHourOffset(float $hourOffset)
287
    {
288
        return static::createFromMinuteOffset($hourOffset * Carbon::MINUTES_PER_HOUR);
289
    }
290
 
291
    /**
292
     * Create a CarbonTimeZone from int/float minute offset.
293
     *
294
     * @param float $minuteOffset number of total minutes of the timezone shift.
295
     *
296
     * @return false|static
297
     */
298
    public static function createFromMinuteOffset(float $minuteOffset)
299
    {
300
        return static::instance(static::getOffsetNameFromMinuteOffset($minuteOffset));
301
    }
302
 
303
    /**
304
     * Convert a total minutes offset into a standardized timezone offset string.
305
     *
306
     * @param float $minutes number of total minutes of the timezone shift.
307
     *
308
     * @return string
309
     */
310
    public static function getOffsetNameFromMinuteOffset(float $minutes): string
311
    {
312
        $minutes = round($minutes);
313
        $unsignedMinutes = abs($minutes);
314
 
315
        return ($minutes < 0 ? '-' : '+').
316
            str_pad((string) floor($unsignedMinutes / 60), 2, '0', STR_PAD_LEFT).
317
            ':'.
318
            str_pad((string) ($unsignedMinutes % 60), 2, '0', STR_PAD_LEFT);
319
    }
320
}