1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
// +---------------------------------------------------------------------------+ |
4
|
|
|
// | This file is part of the Agavi package. | |
5
|
|
|
// | Copyright (c) 2005-2011 the Agavi Project. | |
6
|
|
|
// | | |
7
|
|
|
// | For the full copyright and license information, please view the LICENSE | |
8
|
|
|
// | file that was distributed with this source code. You can also view the | |
9
|
|
|
// | LICENSE file online at http://www.agavi.org/LICENSE.txt | |
10
|
|
|
// | vi: set noexpandtab: | |
11
|
|
|
// | Local Variables: | |
12
|
|
|
// | indent-tabs-mode: t | |
13
|
|
|
// | End: | |
14
|
|
|
// +---------------------------------------------------------------------------+ |
15
|
|
|
|
16
|
|
|
namespace Agavi\Date; |
17
|
|
|
|
18
|
|
|
use Agavi\Translation\Locale; |
19
|
|
|
use Agavi\Translation\TranslationManager; |
20
|
|
|
use Agavi\Util\Toolkit; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Ported from ICU: |
24
|
|
|
* icu/trunk/source/i18n/timezone.cpp r22069 |
25
|
|
|
* icu/trunk/source/i18n/unicode/timezone.h r18762 |
26
|
|
|
* |
27
|
|
|
* Skipped methods: |
28
|
|
|
* getTZDataVersion() - not supported [22063,22069] |
29
|
|
|
* |
30
|
|
|
* |
31
|
|
|
* @package agavi |
32
|
|
|
* @subpackage date |
33
|
|
|
* |
34
|
|
|
* @author Dominik del Bondio <[email protected]> |
35
|
|
|
* @author The ICU Project |
36
|
|
|
* @copyright Authors |
37
|
|
|
* @copyright The Agavi Project |
38
|
|
|
* |
39
|
|
|
* @since 0.11.0 |
40
|
|
|
* |
41
|
|
|
* @version $Id$ |
42
|
|
|
*/ |
43
|
|
|
abstract class TimeZone |
44
|
|
|
{ |
45
|
|
|
/** |
46
|
|
|
* The translation manager instance. |
47
|
|
|
* |
48
|
|
|
* @var TranslationManager |
49
|
|
|
*/ |
50
|
|
|
protected $translationManager = null; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* The id of this time zone. |
54
|
|
|
* |
55
|
|
|
* @var string |
56
|
|
|
*/ |
57
|
|
|
protected $id; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @var string The "resolved" id. This means if the original id pointed |
61
|
|
|
* to a link timezone this will contain the id of the |
62
|
|
|
* timezone the link resolved to. |
63
|
|
|
*/ |
64
|
|
|
protected $resolvedId = null; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Returns the translation manager for this TimeZone. |
68
|
|
|
* |
69
|
|
|
* @return TranslationManager The translation manager. |
70
|
|
|
* |
71
|
|
|
* @author Dominik del Bondio <[email protected]> |
72
|
|
|
* @since 0.11.0 |
73
|
|
|
*/ |
74
|
|
|
public function getTranslationManager() |
75
|
|
|
{ |
76
|
|
|
return $this->translationManager; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* The GMT time zone has a raw offset of zero and does not use daylight |
81
|
|
|
* savings time. This is a commonly used time zone. |
82
|
|
|
* |
83
|
|
|
* @param TranslationManager $tm The translation manager |
84
|
|
|
* |
85
|
|
|
* @return TimeZone The GMT time zone. |
86
|
|
|
* |
87
|
|
|
* @author Dominik del Bondio <[email protected]> |
88
|
|
|
* @author The ICU Project |
89
|
|
|
* @since 0.11.0 |
90
|
|
|
*/ |
91
|
|
|
public static function getGMT(TranslationManager $tm) |
92
|
|
|
{ |
93
|
|
|
return new SimpleTimeZone($tm, 0, 'GMT'); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Overloaded. |
98
|
|
|
* |
99
|
|
|
* @see TimeZone::getOffsetIIIIII() |
100
|
|
|
* @see TimeZone::getOffsetIIIIIII() |
101
|
|
|
* |
102
|
|
|
* @author Dominik del Bondio <[email protected]> |
103
|
|
|
* @since 0.11.0 |
104
|
|
|
*/ |
105
|
|
|
public function getOffset() |
106
|
|
|
{ |
107
|
|
|
$arguments = func_get_args(); |
108
|
|
|
$fName = Toolkit::overloadHelper(array( |
109
|
|
|
array('name' => 'getOffsetIIIIII', |
110
|
|
|
'parameters' => array('int', 'int', 'int', 'int', 'int', 'int')), |
111
|
|
|
array('name' => 'getOffsetIIIIIII', |
112
|
|
|
'parameters' => array('int', 'int', 'int', 'int', 'int', 'int', 'int')), |
113
|
|
|
), |
114
|
|
|
$arguments |
115
|
|
|
); |
116
|
|
|
|
117
|
|
|
return call_user_func_array(array($this, $fName), $arguments); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Returns the time zone raw and GMT offset for the given moment |
122
|
|
|
* in time. Upon return, local-millis = GMT-millis + rawOffset + |
123
|
|
|
* dstOffset. All computations are performed in the proleptic |
124
|
|
|
* Gregorian calendar. The default implementation in the TimeZone |
125
|
|
|
* class delegates to the 8-argument getOffset(). |
126
|
|
|
* |
127
|
|
|
* @param float $date Moment in time for which to return offsets, in units of |
128
|
|
|
* milliseconds from January 1, 1970 0:00 GMT, either GMT |
129
|
|
|
* time or local wall time, depending on `local'. |
130
|
|
|
* @param bool $local If true, `date' is local wall time; otherwise it |
131
|
|
|
* is in GMT time. |
132
|
|
|
* @param int $rawOffset Output parameter to receive the raw offset, that is, the |
133
|
|
|
* offset not including DST adjustments |
134
|
|
|
* @param int $dstOffset Output parameter to receive the DST offset, that is, the |
135
|
|
|
* offset to be added to `rawOffset' to obtain the total |
136
|
|
|
* offset between local and GMT time. If DST is not in |
137
|
|
|
* effect, this value is zero; otherwise it is a positive |
138
|
|
|
* value, typically one hour. |
139
|
|
|
* |
140
|
|
|
* @author Dominik del Bondio <[email protected]> |
141
|
|
|
* @author The ICU Project |
142
|
|
|
* @since 0.11.0 |
143
|
|
|
*/ |
144
|
|
|
public function getOffsetRef($date, $local, &$rawOffset, &$dstOffset) |
145
|
|
|
{ |
146
|
|
|
$rawOffset = $this->getRawOffset(); |
147
|
|
|
|
148
|
|
|
// Convert to local wall millis if necessary |
149
|
|
|
if (!$local) { |
150
|
|
|
$date += $rawOffset; // now in local standard millis |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
// When local==FALSE, we might have to recompute. This loop is |
154
|
|
|
// executed once, unless a recomputation is required; then it is |
155
|
|
|
// executed twice. |
156
|
|
|
for ($pass = 0; true; ++$pass) { |
157
|
|
|
$year = $month = $dom = $dow = 0; |
158
|
|
|
$day = floor($date / DateDefinitions::MILLIS_PER_DAY); |
159
|
|
|
$millis = (int) ($date - $day * DateDefinitions::MILLIS_PER_DAY); |
160
|
|
|
|
161
|
|
|
CalendarGrego::dayToFields($day, $year, $month, $dom, $dow); |
162
|
|
|
|
163
|
|
|
$dstOffset = $this->getOffsetIIIIIII(GregorianCalendar::AD, $year, $month, $dom, $dow, $millis, CalendarGrego::monthLength($year, $month)) - $rawOffset; |
164
|
|
|
|
165
|
|
|
// Recompute if local==FALSE, dstOffset!=0, and addition of |
166
|
|
|
// the dstOffset puts us in a different day. |
167
|
|
|
if ($pass != 0 || $local || $dstOffset == 0) { |
168
|
|
|
break; |
169
|
|
|
} |
170
|
|
|
$date += $dstOffset; |
171
|
|
|
if (floor($date / DateDefinitions::MILLIS_PER_DAY) == $day) { |
172
|
|
|
break; |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Sets the TimeZone's raw GMT offset (i.e., the number of milliseconds to |
179
|
|
|
* add to GMT to get local time, before taking daylight savings time into |
180
|
|
|
* account). |
181
|
|
|
* |
182
|
|
|
* @param int $offsetMillis The new raw GMT offset for this time zone. |
183
|
|
|
* |
184
|
|
|
* @author Dominik del Bondio <[email protected]> |
185
|
|
|
* @author The ICU Project |
186
|
|
|
* @since 0.11.0 |
187
|
|
|
*/ |
188
|
|
|
abstract public function setRawOffset($offsetMillis); |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Returns the TimeZone's raw GMT offset (i.e., the number of milliseconds to |
192
|
|
|
* add to GMT to get local time, before taking daylight savings time into |
193
|
|
|
* account). |
194
|
|
|
* |
195
|
|
|
* @return int The TimeZone's raw GMT offset. |
196
|
|
|
* |
197
|
|
|
* @author Dominik del Bondio <[email protected]> |
198
|
|
|
* @author The ICU Project |
199
|
|
|
* @since 0.11.0 |
200
|
|
|
*/ |
201
|
|
|
abstract public function getRawOffset(); |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Returns the TimeZone's ID. |
205
|
|
|
* |
206
|
|
|
* @return string This TimeZone's ID. |
207
|
|
|
* |
208
|
|
|
* @author Dominik del Bondio <[email protected]> |
209
|
|
|
* @author The ICU Project |
210
|
|
|
* @since 0.11.0 |
211
|
|
|
*/ |
212
|
|
|
public function getId() |
213
|
|
|
{ |
214
|
|
|
return $this->id; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* Sets the TimeZone's ID to the specified value. This doesn't affect any |
219
|
|
|
* other fields (for example, if you say |
220
|
|
|
* <code> |
221
|
|
|
* $foo = $tm->createTimeZone('America/New_York'); |
222
|
|
|
* $foo->setId('America/Los_Angeles'); |
223
|
|
|
* </code> |
224
|
|
|
* the time zone's GMT offset and daylight-savings rules don't change to those |
225
|
|
|
* for Los Angeles. They're still those for New York. Only the ID has |
226
|
|
|
* changed.) |
227
|
|
|
* |
228
|
|
|
* @param string $id The new timezone ID. |
229
|
|
|
* |
230
|
|
|
* @author Dominik del Bondio <[email protected]> |
231
|
|
|
* @author The ICU Project |
232
|
|
|
* @since 0.11.0 |
233
|
|
|
*/ |
234
|
|
|
public function setId($id) |
235
|
|
|
{ |
236
|
|
|
$this->id = $id; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Returns the resolved TimeZone's ID. |
241
|
|
|
* |
242
|
|
|
* @return string This TimeZone's ID. |
243
|
|
|
* |
244
|
|
|
* @author Dominik del Bondio <[email protected]> |
245
|
|
|
* @author The ICU Project |
246
|
|
|
* @since 0.11.0 |
247
|
|
|
*/ |
248
|
|
|
public function getResolvedId() |
249
|
|
|
{ |
250
|
|
|
if ($this->resolvedId === null) { |
251
|
|
|
return $this->id; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
return $this->resolvedId; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Sets the resolved TimeZone's ID. |
259
|
|
|
* |
260
|
|
|
* @param string $id The resolved timezone ID. |
261
|
|
|
* |
262
|
|
|
* @author Dominik del Bondio <[email protected]> |
263
|
|
|
* @author The ICU Project |
264
|
|
|
* @since 0.11.0 |
265
|
|
|
*/ |
266
|
|
|
public function setResolvedId($id) |
267
|
|
|
{ |
268
|
|
|
$this->resolvedId = $id; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Enum for use with getDisplayName |
273
|
|
|
* @stable ICU 2.4 |
274
|
|
|
*/ |
275
|
|
|
/** |
276
|
|
|
* Selector for short display name |
277
|
|
|
* @stable ICU 2.4 |
278
|
|
|
*/ |
279
|
|
|
const SHORT = 1; |
280
|
|
|
/** |
281
|
|
|
* Selector for long display name |
282
|
|
|
* @stable ICU 2.4 |
283
|
|
|
*/ |
284
|
|
|
const LONG = 2; |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* Returns a name of this time zone suitable for presentation to the user |
288
|
|
|
* in the specified locale. |
289
|
|
|
* If the display name is not available for the locale, |
290
|
|
|
* then this method returns a string in the format |
291
|
|
|
* <code>GMT[+-]hh:mm</code>. |
292
|
|
|
* |
293
|
|
|
* @param bool $daylight If true, return the daylight savings name. |
294
|
|
|
* @param int $style Either <code>self::LONG</code> or <code>self::SHORT</code> |
295
|
|
|
* @param Locale $locale The locale in which to supply the display name. |
296
|
|
|
* |
297
|
|
|
* @return string the human-readable name of this time zone in the given |
298
|
|
|
* locale or in the default locale if the given locale is |
299
|
|
|
* not recognized. |
300
|
|
|
* |
301
|
|
|
* @author Dominik del Bondio <[email protected]> |
302
|
|
|
* @author The ICU Project |
303
|
|
|
* @since 0.11.0 |
304
|
|
|
*/ |
305
|
|
|
public function getDisplayName($daylight = null, $style = null, Locale $locale = null) |
306
|
|
|
{ |
307
|
|
|
if ($daylight === null) { |
308
|
|
|
$daylight = false; |
309
|
|
|
$style = self::LONG; |
310
|
|
|
$locale = $this->translationManager->getCurrentLocale(); |
311
|
|
|
} elseif ($daylight instanceof Locale) { |
312
|
|
|
$locale = $daylight; |
313
|
|
|
$daylight = false; |
314
|
|
|
$style = self::LONG; |
315
|
|
|
} elseif (is_bool($daylight) && $style !== null) { |
316
|
|
|
if ($locale === null) { |
317
|
|
|
$locale = $this->translationManager->getCurrentLocale(); |
318
|
|
|
} |
319
|
|
|
} else { |
320
|
|
|
throw new \InvalidArgumentException('Illegal arguments for TimeZone::getDisplayName'); |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
$displayString = null; |
|
|
|
|
324
|
|
|
|
325
|
|
|
if ($daylight && $this->useDaylightTime()) { |
326
|
|
|
if ($style == self::LONG) { |
327
|
|
|
$displayString = $locale->getTimeZoneLongDaylightName($this->getId()); |
328
|
|
|
} else { |
329
|
|
|
$displayString = $locale->getTimeZoneShortDaylightName($this->getId()); |
330
|
|
|
} |
331
|
|
|
} else { |
332
|
|
|
if ($style == self::LONG) { |
333
|
|
|
$displayString = $locale->getTimeZoneLongStandardName($this->getId()); |
334
|
|
|
} else { |
335
|
|
|
$displayString = $locale->getTimeZoneShortStandardName($this->getId()); |
336
|
|
|
} |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
if (!$displayString) { |
340
|
|
|
$displayString = $this->formatOffset($daylight); |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
return $displayString; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Returns the GMT+-hh:mm representation of this timezone. |
348
|
|
|
* |
349
|
|
|
* @param bool $daylight Whether dst is active. |
350
|
|
|
* @param string $separator The hour/minute and minute/second separator. |
351
|
|
|
* @param string $prefix A prefix to be added in front of the string. |
352
|
|
|
* |
353
|
|
|
* @return string The formatted representation. |
354
|
|
|
* |
355
|
|
|
* @author Dominik del Bondio <[email protected]> |
356
|
|
|
* @since 1.0.2 |
357
|
|
|
*/ |
358
|
|
|
public function formatOffset($daylight, $separator = ':', $prefix = 'GMT') |
359
|
|
|
{ |
360
|
|
|
$value = $this->getRawOffset() + ($daylight ? $this->getDSTSavings() : 0); |
361
|
|
|
|
362
|
|
|
if ($value < 0) { |
363
|
|
|
$str = sprintf('%s-', $prefix); |
364
|
|
|
$value = -$value; // suppress the '-' sign for text display. |
365
|
|
|
} else { |
366
|
|
|
$str = sprintf('%s+', $prefix); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
$str .= str_pad((int) ($value / DateDefinitions::MILLIS_PER_HOUR), 2, '0', STR_PAD_LEFT) |
370
|
|
|
. $separator |
371
|
|
|
. str_pad((int) (($value % DateDefinitions::MILLIS_PER_HOUR) / DateDefinitions::MILLIS_PER_MINUTE), 2, '0', STR_PAD_LEFT); |
372
|
|
|
$offsetSeconds = ((int) ($value / DateDefinitions::MILLIS_PER_SECOND) % 60); |
373
|
|
|
if ($offsetSeconds) { |
374
|
|
|
$str .= $separator . str_pad($offsetSeconds, 2, '0', STR_PAD_LEFT); |
375
|
|
|
} |
376
|
|
|
return $str; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/** |
380
|
|
|
* Queries if this time zone uses daylight savings time. |
381
|
|
|
* |
382
|
|
|
* @return bool If this time zone uses daylight savings time, |
383
|
|
|
* false, otherwise. |
384
|
|
|
* |
385
|
|
|
* @author Dominik del Bondio <[email protected]> |
386
|
|
|
* @author The ICU Project |
387
|
|
|
* @since 0.11.0 |
388
|
|
|
*/ |
389
|
|
|
abstract public function useDaylightTime(); |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* Returns true if this zone has the same rule and offset as another zone. |
393
|
|
|
* That is, if this zone differs only in ID, if at all. |
394
|
|
|
* |
395
|
|
|
* @param TimeZone $other The object to be compared with |
396
|
|
|
* |
397
|
|
|
* @return bool True if the given zone is the same as this one, |
398
|
|
|
* with the possible exception of the ID |
399
|
|
|
* |
400
|
|
|
* @author Dominik del Bondio <[email protected]> |
401
|
|
|
* @author The ICU Project |
402
|
|
|
* @since 0.11.0 |
403
|
|
|
*/ |
404
|
|
|
public function hasSameRules(TimeZone $other) |
405
|
|
|
{ |
406
|
|
|
return ($this->getRawOffset() == $other->getRawOffset() && |
407
|
|
|
$this->useDaylightTime() == $other->useDaylightTime()); |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
/** |
411
|
|
|
* Returns the amount of time to be added to local standard time |
412
|
|
|
* to get local wall clock time. |
413
|
|
|
* <p> |
414
|
|
|
* The default implementation always returns 3600000 milliseconds |
415
|
|
|
* (i.e., one hour) if this time zone observes Daylight Saving |
416
|
|
|
* Time. Otherwise, 0 (zero) is returned. |
417
|
|
|
* <p> |
418
|
|
|
* If an underlying TimeZone implementation subclass supports |
419
|
|
|
* historical Daylight Saving Time changes, this method returns |
420
|
|
|
* the known latest daylight saving value. |
421
|
|
|
* |
422
|
|
|
* @return int The amount of saving time in milliseconds |
423
|
|
|
* |
424
|
|
|
* @author Dominik del Bondio <[email protected]> |
425
|
|
|
* @author The ICU Project |
426
|
|
|
* @since 0.11.0 |
427
|
|
|
*/ |
428
|
|
|
public function getDSTSavings() |
429
|
|
|
{ |
430
|
|
|
if ($this->useDaylightTime()) { |
431
|
|
|
return 3600000; |
432
|
|
|
} |
433
|
|
|
return 0; |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* Construct a timezone with a given ID. |
438
|
|
|
* |
439
|
|
|
* @param TranslationManager $tm The translation Manager |
440
|
|
|
* @param string $id A system time zone ID |
441
|
|
|
* |
442
|
|
|
* @author Dominik del Bondio <[email protected]> |
443
|
|
|
* @author The ICU Project |
444
|
|
|
* @since 0.11.0 |
445
|
|
|
*/ |
446
|
|
|
protected function __construct(TranslationManager $tm, $id = '') |
447
|
|
|
{ |
448
|
|
|
$this->translationManager = $tm; |
449
|
|
|
$this->id = $id; |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* Returns the TimeZone's adjusted GMT offset (i.e., the number of |
454
|
|
|
* milliseconds to add to GMT to get local time in this time zone, taking |
455
|
|
|
* daylight savings time into account) as of a particular reference date. |
456
|
|
|
* The reference date is used to determine whether daylight savings time is |
457
|
|
|
* in effect and needs to be figured into the offset that is returned (in |
458
|
|
|
* other words, what is the adjusted GMT offset in this time zone at this |
459
|
|
|
* particular date and time?). For the time zones produced by |
460
|
|
|
* createTimeZone(), the reference data is specified according to the |
461
|
|
|
* Gregorian calendar, and the date and time fields are local standard time. |
462
|
|
|
* |
463
|
|
|
* <p>Note: Don't call this method. Instead, call the getOffsetRef() which |
464
|
|
|
* returns both the raw and the DST offset for a given time. This method |
465
|
|
|
* is retained only for backward compatibility. |
466
|
|
|
* |
467
|
|
|
* @param int $era The reference date's era |
468
|
|
|
* @param int $year The reference date's year |
469
|
|
|
* @param int $month The reference date's month (0-based; 0 is January) |
470
|
|
|
* @param int $day The reference date's day-in-month (1-based) |
471
|
|
|
* @param int $dayOfWeek The reference date's day-of-week (1-based; 1 is Sunday) |
472
|
|
|
* @param int $millis The reference date's milliseconds in day, local standard |
473
|
|
|
* time |
474
|
|
|
* |
475
|
|
|
* @return int The offset in milliseconds to add to GMT to get local time. |
476
|
|
|
* |
477
|
|
|
* @author Dominik del Bondio <[email protected]> |
478
|
|
|
* @author The ICU Project |
479
|
|
|
* @since 0.11.0 |
480
|
|
|
*/ |
481
|
|
|
abstract protected function getOffsetIIIIII($era, $year, $month, $day, $dayOfWeek, $millis); |
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* Gets the time zone offset, for current date, modified in case of |
485
|
|
|
* daylight savings. This is the offset to add *to* UTC to get local time. |
486
|
|
|
* |
487
|
|
|
* <p>Note: Don't call this method. Instead, call the getOffsetRef(), which |
488
|
|
|
* returns both the raw and the DST offset for a given time. This method |
489
|
|
|
* is retained only for backward compatibility. |
490
|
|
|
* |
491
|
|
|
* @param int $era The era of the given date. |
492
|
|
|
* @param int $year The year in the given date. |
493
|
|
|
* @param int $month The month in the given date. |
494
|
|
|
* Month is 0-based. e.g., 0 for January. |
495
|
|
|
* @param int $day The day-in-month of the given date. |
496
|
|
|
* @param int $dayOfWeek The day-of-week of the given date. |
497
|
|
|
* @param int $milliseconds The millis in day in <em>standard</em> local time. |
498
|
|
|
* @param int $monthLength The length of the given month in days. |
499
|
|
|
* |
500
|
|
|
* @return int The offset to add *to* GMT to get local time. |
501
|
|
|
* |
502
|
|
|
* @author Dominik del Bondio <[email protected]> |
503
|
|
|
* @author The ICU Project |
504
|
|
|
* @since 0.11.0 |
505
|
|
|
*/ |
506
|
|
|
abstract protected function getOffsetIIIIIII($era, $year, $month, $day, $dayOfWeek, $milliseconds, $monthLength); |
507
|
|
|
|
508
|
|
|
/** |
509
|
|
|
* Parse a custom time zone identifier and return a corresponding zone. |
510
|
|
|
* |
511
|
|
|
* @param TranslationManager $tm The translation manager |
512
|
|
|
* @param string $id A string of the form GMT[+-]hh:mm, GMT[+-]hhmm, or |
513
|
|
|
* GMT[+-]hh. |
514
|
|
|
* |
515
|
|
|
* @return TimeZone A newly created SimpleTimeZone with the |
516
|
|
|
* given offset and no Daylight Savings Time, or |
517
|
|
|
* null if the id cannot be parsed. |
518
|
|
|
* |
519
|
|
|
* @author Dominik del Bondio <[email protected]> |
520
|
|
|
* @author The ICU Project |
521
|
|
|
* @since 0.11.0 |
522
|
|
|
*/ |
523
|
|
|
public static function createCustomTimeZone(TranslationManager $tm, $id) |
524
|
|
|
{ |
525
|
|
|
$maxCustomHour = 23; |
526
|
|
|
$maxCustomMin = 59; |
527
|
|
|
$maxCustomSec = 59; |
528
|
|
|
|
529
|
|
|
$hours = 0; |
|
|
|
|
530
|
|
|
$minutes = 0; |
531
|
|
|
$seconds = 0; |
532
|
|
|
$negative = false; |
|
|
|
|
533
|
|
|
if (preg_match('#^GMT([+-])(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?$#', $id, $match)) { |
534
|
|
|
$negative = $match[1] == '-'; |
535
|
|
|
$hours = $match[2]; |
536
|
|
|
$minutes = $match[3]; |
537
|
|
|
$seconds = isset($match[4]) ? $match[4] : 0; |
538
|
|
|
} elseif (preg_match('#^GMT([+-])(\d{1,6})$#', $id, $match)) { |
539
|
|
|
$negative = $match[1] == '-'; |
540
|
|
|
// Supported formats are below - |
541
|
|
|
// |
542
|
|
|
// HHmmss |
543
|
|
|
// Hmmss |
544
|
|
|
// HHmm |
545
|
|
|
// Hmm |
546
|
|
|
// HH |
547
|
|
|
// H |
548
|
|
|
$hours = $match[2]; |
549
|
|
|
switch (strlen($hours)) { |
550
|
|
|
case 1: |
551
|
|
|
case 2: |
552
|
|
|
// already set to hour |
553
|
|
|
break; |
554
|
|
|
case 3: |
555
|
|
|
case 4: |
556
|
|
|
$minutes = $hours % 100; |
557
|
|
|
$hours = (int) ($hours / 100); |
558
|
|
|
break; |
559
|
|
|
case 5: |
560
|
|
|
case 6: |
561
|
|
|
$seconds = $hours % 100; |
562
|
|
|
$minutes = ((int)($hours / 100)) % 100; |
563
|
|
|
$hours = (int) ($hours / 10000); |
564
|
|
|
break; |
565
|
|
|
} |
566
|
|
|
} else { |
567
|
|
|
throw new \InvalidArgumentException('Zone identifier is not parseable'); |
568
|
|
|
} |
569
|
|
|
|
570
|
|
|
if ($hours > $maxCustomHour || $minutes > $maxCustomMin || $seconds > $maxCustomSec) { |
571
|
|
|
throw new \InvalidArgumentException('Zone identifier is not parseable'); |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
$offset = $hours * 3600 + $minutes * 60 + $seconds; |
575
|
|
|
|
576
|
|
|
if ($negative) { |
577
|
|
|
$offset = -$offset; |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
// create the timezone with an empty id and set it afterwards |
581
|
|
|
$tz = new SimpleTimeZone($tm, $offset * 1000.0); |
582
|
|
|
$tz->setId($tz->formatOffset(false, '')); |
583
|
|
|
return $tz; |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
/** |
587
|
|
|
* Returns true if the two TimeZones are equal. (The TimeZone version |
588
|
|
|
* only compares IDs, but subclasses are expected to also compare the fields |
589
|
|
|
* they add.) |
590
|
|
|
* |
591
|
|
|
* @param TimeZone $that The object to be compared with. |
592
|
|
|
* |
593
|
|
|
* @return bool True if the given TimeZone is equal to this |
594
|
|
|
* TimeZone; false otherwise. |
595
|
|
|
* |
596
|
|
|
* @author Dominik del Bondio <[email protected]> |
597
|
|
|
* @author The ICU Project |
598
|
|
|
* @since 0.11.0 |
599
|
|
|
*/ |
600
|
|
|
public function __is_equal(TimeZone $that) |
601
|
|
|
{ |
602
|
|
|
return get_class($this) == get_class($that) && $this->getId() == $that->getId(); |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
/** |
606
|
|
|
* Returns true if the two TimeZones are NOT equal; that is, if operator==() |
607
|
|
|
* returns false. |
608
|
|
|
* |
609
|
|
|
* @param TimeZone $that The object to be compared with. |
610
|
|
|
* |
611
|
|
|
* @return bool True if the given TimeZone is not equal to this |
612
|
|
|
* TimeZone; false otherwise. |
613
|
|
|
* |
614
|
|
|
* @author Dominik del Bondio <[email protected]> |
615
|
|
|
* @author The ICU Project |
616
|
|
|
* @since 0.11.0 |
617
|
|
|
*/ |
618
|
|
|
public function __is_not_equal(TimeZone $that) |
619
|
|
|
{ |
620
|
|
|
return get_class($this) != get_class($that) || $this->getId() != $that->getId(); |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/** |
624
|
|
|
* Queries if the given date is in daylight savings time in |
625
|
|
|
* this time zone. |
626
|
|
|
* This method is wasteful since it creates a new GregorianCalendar and |
627
|
|
|
* deletes it each time it is called. |
628
|
|
|
* |
629
|
|
|
* @param float $date The given time |
630
|
|
|
* |
631
|
|
|
* @return bool True if the given date is in daylight savings time, |
632
|
|
|
* false, otherwise. |
633
|
|
|
* |
634
|
|
|
* @author Dominik del Bondio <[email protected]> |
635
|
|
|
* @author The ICU Project |
636
|
|
|
* @since 0.11.0 |
637
|
|
|
*/ |
638
|
|
|
public function inDaylightTime($date) |
639
|
|
|
{ |
640
|
|
|
$cal = new GregorianCalendar($this); |
641
|
|
|
$cal->setTime($date); |
642
|
|
|
return $cal->inDaylightTime(); |
643
|
|
|
} |
644
|
|
|
} |
645
|
|
|
|
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.