Passed
Push — release-2.1 ( bb7f39...4ba5dd )
by Mathias
06:31
created

get_tzid_fallbacks()   B

Complexity

Conditions 9
Paths 36

Size

Total Lines 137
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 69
nc 36
nop 2
dl 0
loc 137
rs 7.1208
c 1
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file provides some functions to simplify working with time zones.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines https://www.simplemachines.org
10
 * @copyright 2020 Simple Machines and individual contributors
11
 * @license https://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 RC3
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * Returns an array that instructs SMF how to map specific time zones
21
 * (e.g. "America/Denver") onto the user-friendly "meta-zone" labels that
22
 * most people think of as time zones (e.g. "Mountain Time").
23
 *
24
 * @param string $when The date/time used to determine fallback values.
25
 *		May be a Unix timestamp or any string that strtotime() can understand.
26
 *		Defaults to 'now'.
27
 * @return array An array relating time zones to "meta-zones"
28
 */
29
function get_tzid_metazones($when = 'now')
30
{
31
	global $txt, $tztxt;
32
33
	// This should already have been loaded, but just in case...
34
	loadLanguage('Timezones');
35
36
	/*
37
		This array lists a series of representative time zones and their
38
		corresponding "meta-zone" labels.
39
40
		The term "representative" here means that a given time zone can
41
		represent others that use exactly the same rules for DST
42
		transitions, UTC offsets, and abbreviations. For example,
43
		Europe/Berlin can be representative for Europe/Rome,
44
		Europe/Paris, etc., because these cities all use exactly the
45
		same time zone rules and values.
46
47
		Meta-zone labels are the user friendly strings shown to the end
48
		user, e.g. "Mountain Standard Time". The values of this array
49
		are keys of strings defined in Timezones.{language}.php, which
50
		in turn are sprintf format strings used to generate the final
51
		label text.
52
53
		Sometimes several representative time zones will map onto the
54
		same meta-zone label. This usually happens when there are
55
		different rules for Daylight Saving time in locations that are
56
		otherwise the same. For example, both America/Denver and
57
		America/Phoenix map to North_America_Mountain, but the ultimate
58
		output will be 'Mountain Time (MST/MDT)' for America/Denver vs.
59
		'Mountain Standard Time (MST)' for America/Phoenix.
60
61
		If you are adding a new meta-zone to this list because the TZDB
62
		added a new time zone that doesn't fit any existing meta-zone,
63
		please also add a fallback in the get_tzid_fallbacks() function.
64
		This helps support SMF installs on servers using outdated
65
		versions of the TZDB.
66
	 */
67
	$tzid_metazones = array(
68
		// No DST
69
		'Africa/Abidjan' => 'GMT',
70
71
		// No DST
72
		'Africa/Algiers' => 'Europe_Central',
73
74
		// Uses DST
75
		'Africa/Casablanca' => 'Africa_Morocco',
76
77
		// No DST
78
		'Africa/Johannesburg' => 'Africa_South',
79
80
		// No DST
81
		'Africa/Lagos' => 'Africa_West',
82
83
		// No DST
84
		'Africa/Maputo' => 'Africa_Central',
85
86
		// No DST
87
		'Africa/Nairobi' => 'Africa_East',
88
89
		// Uses DST
90
		'America/Adak' => 'North_America_Hawaii_Aleutian',
91
92
		// Uses DST
93
		'America/Anchorage' => 'North_America_Alaska',
94
95
		// No DST
96
		'America/Argentina/Buenos_Aires' => 'South_America_Argentina',
97
98
		// Uses DST
99
		'America/Asuncion' => 'South_America_Paraguay',
100
101
		// No DST
102
		'America/Belize' => 'North_America_Central',
103
104
		// No DST
105
		'America/Bogota' => 'South_America_Colombia',
106
107
		// No DST
108
		'America/Caracas' => 'South_America_Venezuela',
109
110
		// No DST
111
		'America/Cayenne' => 'South_America_French_Guiana',
112
113
		// Uses DST
114
		'America/Chicago' => 'North_America_Central',
115
116
		// Uses DST
117
		'America/Chihuahua' => 'North_America_Mexico_Pacific',
118
119
		// Uses DST
120
		'America/Denver' => 'North_America_Mountain',
121
122
		// Uses DST
123
		'America/Nuuk' => 'North_America_Greenland_Western',
124
125
		// No DST
126
		'America/Guayaquil' => 'South_America_Ecuador',
127
128
		// No DST
129
		'America/Guyana' => 'South_America_Guyana',
130
131
		// Uses DST
132
		'America/Halifax' => 'North_America_Atlantic',
133
134
		// Uses DST
135
		'America/Havana' => 'North_America_Cuba',
136
137
		// No DST
138
		'America/Jamaica' => 'North_America_Eastern',
139
140
		// No DST
141
		'America/La_Paz' => 'South_America_Bolivia',
142
143
		// No DST
144
		'America/Lima' => 'South_America_Peru',
145
146
		// Uses DST
147
		'America/Los_Angeles' => 'North_America_Pacific',
148
149
		// No DST
150
		'America/Manaus' => 'South_America_Amazon',
151
152
		// Uses DST
153
		'America/Mexico_City' => 'North_America_Mexico_Central',
154
155
		// Uses DST
156
		'America/Miquelon' => 'North_America_St_Pierre_Miquelon',
157
158
		// No DST
159
		'America/Montevideo' => 'South_America_Uruguay',
160
161
		// Uses DST
162
		'America/New_York' => 'North_America_Eastern',
163
164
		// No DST
165
		'America/Noronha' => 'South_America_Noronha',
166
167
		// No DST
168
		'America/Paramaribo' => 'South_America_Suriname',
169
170
		// No DST
171
		'America/Phoenix' => 'North_America_Mountain',
172
173
		// No DST
174
		'America/Port_of_Spain' => 'North_America_Atlantic',
175
176
		// No DST
177
		'America/Punta_Arenas' => 'South_America_Chile_Magallanes',
178
179
		// No DST
180
		'America/Rio_Branco' => 'South_America_Acre',
181
182
		// Uses DST
183
		'America/Santiago' => 'South_America_Chile',
184
185
		// No DST
186
		'America/Sao_Paulo' => 'South_America_Brasilia',
187
188
		// Uses DST
189
		'America/Scoresbysund' => 'North_America_Greenland_Eastern',
190
191
		// Uses DST
192
		'America/St_Johns' => 'North_America_Newfoundland',
193
194
		// No DST
195
		'Antarctica/Casey' => 'Antarctica_Casey',
196
197
		// No DST
198
		'Antarctica/Davis' => 'Antarctica_Davis',
199
200
		// No DST
201
		'Antarctica/DumontDUrville' => 'Antarctica_DumontDUrville',
202
203
		// No DST
204
		'Antarctica/Macquarie' => 'Antarctica_Macquarie',
205
206
		// No DST
207
		'Antarctica/Mawson' => 'Antarctica_Mawson',
208
209
		// Uses DST
210
		'Antarctica/McMurdo' => 'Antarctica_McMurdo',
211
212
		// No DST
213
		'Antarctica/Palmer' => 'Antarctica_Palmer',
214
215
		// No DST
216
		'Antarctica/Rothera' => 'Antarctica_Rothera',
217
218
		// No DST
219
		'Antarctica/Syowa' => 'Antarctica_Syowa',
220
221
		// Uses DST
222
		'Antarctica/Troll' => 'Antarctica_Troll',
223
224
		// No DST
225
		'Antarctica/Vostok' => 'Antarctica_Vostok',
226
227
		// No DST
228
		'Asia/Almaty' => 'Asia_Kazakhstan_Eastern',
229
230
		// Uses DST
231
		'Asia/Amman' => 'Asia_Jordan',
232
233
		// No DST
234
		'Asia/Aqtau' => 'Asia_Kazakhstan_Western',
235
236
		// No DST
237
		'Asia/Ashgabat' => 'Asia_Turkmenistan',
238
239
		// No DST
240
		'Asia/Baku' => 'Asia_Azerbaijan',
241
242
		// No DST
243
		'Asia/Bangkok' => 'Asia_Southeast',
244
245
		// Uses DST
246
		'Asia/Beirut' => 'Asia_Libya',
247
248
		// No DST
249
		'Asia/Bishkek' => 'Asia_Kyrgystan',
250
251
		// No DST
252
		'Asia/Brunei' => 'Asia_Brunei',
253
254
		// Uses DST
255
		'Asia/Damascus' => 'Asia_Damascus',
256
257
		// No DST
258
		'Asia/Dhaka' => 'Asia_Bangladesh',
259
260
		// No DST
261
		'Asia/Dili' => 'Asia_East_Timor',
262
263
		// No DST
264
		'Asia/Dubai' => 'Asia_Gulf',
265
266
		// No DST
267
		'Asia/Dushanbe' => 'Asia_Tajikistan',
268
269
		// Uses DST
270
		'Asia/Gaza' => 'Asia_Palestine',
271
272
		// No DST
273
		'Asia/Hong_Kong' => 'Asia_Hong_Kong',
274
275
		// No DST
276
		'Asia/Hovd' => 'Asia_Mongolia_Western',
277
278
		// No DST
279
		'Asia/Irkutsk' => 'Asia_Irkutsk',
280
281
		// No DST
282
		'Asia/Jakarta' => 'Asia_Indonesia_Western',
283
284
		// No DST
285
		'Asia/Jayapura' => 'Asia_Indonesia_Eastern',
286
287
		// Uses DST
288
		'Asia/Jerusalem' => 'Asia_Israel',
289
290
		// No DST
291
		'Asia/Kabul' => 'Asia_Afghanistan',
292
293
		// No DST
294
		'Asia/Kamchatka' => 'Asia_Kamchatka',
295
296
		// No DST
297
		'Asia/Karachi' => 'Asia_Pakistan',
298
299
		// No DST
300
		'Asia/Kathmandu' => 'Asia_Nepal',
301
302
		// No DST
303
		'Asia/Kolkata' => 'Asia_India',
304
305
		// No DST
306
		'Asia/Krasnoyarsk' => 'Asia_Krasnoyarsk',
307
308
		// No DST
309
		'Asia/Kuala_Lumpur' => 'Asia_Malaysia',
310
311
		// No DST
312
		'Asia/Magadan' => 'Asia_Magadan',
313
314
		// No DST
315
		'Asia/Makassar' => 'Asia_Indonesia_Central',
316
317
		// No DST
318
		'Asia/Manila' => 'Asia_Philippines',
319
320
		// No DST
321
		'Asia/Omsk' => 'Asia_Omsk',
322
323
		// No DST
324
		'Asia/Riyadh' => 'Asia_Arabia',
325
326
		// No DST
327
		'Asia/Seoul' => 'Asia_Korea',
328
329
		// No DST
330
		'Asia/Shanghai' => 'Asia_China',
331
332
		// No DST
333
		'Asia/Singapore' => 'Asia_Singapore',
334
335
		// No DST
336
		'Asia/Taipei' => 'Asia_Taiwan',
337
338
		// No DST
339
		'Asia/Tashkent' => 'Asia_Uzbekistan',
340
341
		// No DST
342
		'Asia/Tbilisi' => 'Asia_Georgia',
343
344
		// Uses DST
345
		'Asia/Tehran' => 'Asia_Iran',
346
347
		// No DST
348
		'Asia/Thimphu' => 'Asia_Bhutan',
349
350
		// No DST
351
		'Asia/Tokyo' => 'Asia_Japan',
352
353
		// No DST
354
		'Asia/Ulaanbaatar' => 'Asia_Mongolia_Eastern',
355
356
		// No DST
357
		'Asia/Vladivostok' => 'Asia_Vladivostok',
358
359
		// No DST
360
		'Asia/Yakutsk' => 'Asia_Yakutsk',
361
362
		// No DST
363
		'Asia/Yangon' => 'Asia_Myanmar',
364
365
		// No DST
366
		'Asia/Yekaterinburg' => 'Asia_Yekaterinburg',
367
368
		// No DST
369
		'Asia/Yerevan' => 'Asia_Armenia',
370
371
		// Uses DST
372
		'Atlantic/Azores' => 'Atlantic_Azores',
373
374
		// No DST
375
		'Atlantic/Cape_Verde' => 'Atlantic_Cape_Verde',
376
377
		// No DST
378
		'Atlantic/South_Georgia' => 'Atlantic_South_Georgia',
379
380
		// No DST
381
		'Atlantic/Stanley' => 'Atlantic_Falkland',
382
383
		// Uses DST
384
		'Australia/Adelaide' => 'Australia_Central',
385
386
		// No DST
387
		'Australia/Brisbane' => 'Australia_Eastern',
388
389
		// No DST
390
		'Australia/Darwin' => 'Australia_Central',
391
392
		// No DST
393
		'Australia/Eucla' => 'Australia_CentralWestern',
394
395
		// Uses DST
396
		'Australia/Lord_Howe' => 'Australia_Lord_Howe',
397
398
		// Uses DST
399
		'Australia/Melbourne' => 'Australia_Eastern',
400
401
		// No DST
402
		'Australia/Perth' => 'Australia_Western',
403
404
		// Uses DST
405
		'Europe/Berlin' => 'Europe_Central',
406
407
		// Uses DST
408
		'Europe/Chisinau' => 'Europe_Moldova',
409
410
		// Uses DST
411
		'Europe/Dublin' => 'Europe_Eire',
412
413
		// Uses DST
414
		'Europe/Helsinki' => 'Europe_Eastern',
415
416
		// No DST
417
		'Europe/Istanbul' => 'Asia_Turkey',
418
419
		// No DST
420
		'Europe/Kaliningrad' => 'Europe_Eastern',
421
422
		// Uses DST
423
		'Europe/Lisbon' => 'Europe_Western',
424
425
		// Uses DST
426
		'Europe/London' => 'Europe_UK',
427
428
		// No DST
429
		'Europe/Minsk' => 'Europe_Minsk',
430
431
		// No DST
432
		'Europe/Moscow' => 'Europe_Moscow',
433
434
		// No DST
435
		'Europe/Samara' => 'Europe_Samara',
436
437
		// No DST
438
		'Europe/Volgograd' => 'Europe_Volgograd',
439
440
		// No DST
441
		'Indian/Chagos' => 'Indian_Chagos',
442
443
		// No DST
444
		'Indian/Christmas' => 'Indian_Christmas',
445
446
		// No DST
447
		'Indian/Cocos' => 'Indian_Cocos',
448
449
		// No DST
450
		'Indian/Kerguelen' => 'Indian_Kerguelen',
451
452
		// No DST
453
		'Indian/Mahe' => 'Indian_Seychelles',
454
455
		// No DST
456
		'Indian/Maldives' => 'Indian_Maldives',
457
458
		// No DST
459
		'Indian/Mauritius' => 'Indian_Mauritius',
460
461
		// No DST
462
		'Indian/Reunion' => 'Indian_Reunion',
463
464
		// Uses DST
465
		'Pacific/Apia' => 'Pacific_Apia',
466
467
		// Uses DST
468
		'Pacific/Auckland' => 'Pacific_New_Zealand',
469
470
		// No DST
471
		'Pacific/Bougainville' => 'Pacific_Bougainville',
472
473
		// Uses DST
474
		'Pacific/Chatham' => 'Pacific_Chatham',
475
476
		// No DST
477
		'Pacific/Chuuk' => 'Pacific_Chuuk',
478
479
		// Uses DST
480
		'Pacific/Easter' => 'Pacific_Easter',
481
482
		// No DST
483
		'Pacific/Efate' => 'Pacific_Vanuatu',
484
485
		// No DST
486
		'Pacific/Enderbury' => 'Pacific_Phoenix_Islands',
487
488
		// No DST
489
		'Pacific/Fakaofo' => 'Pacific_Tokelau',
490
491
		// Uses DST
492
		'Pacific/Fiji' => 'Pacific_Fiji',
493
494
		// No DST
495
		'Pacific/Funafuti' => 'Pacific_Tuvalu',
496
497
		// No DST
498
		'Pacific/Galapagos' => 'Pacific_Galapagos',
499
500
		// No DST
501
		'Pacific/Gambier' => 'Pacific_Gambier',
502
503
		// No DST
504
		'Pacific/Guadalcanal' => 'Pacific_Solomon',
505
506
		// No DST
507
		'Pacific/Guam' => 'Pacific_Chamorro',
508
509
		// No DST
510
		'Pacific/Honolulu' => 'Pacific_Hawaii',
511
512
		// No DST
513
		'Pacific/Kiritimati' => 'Pacific_Line',
514
515
		// No DST
516
		'Pacific/Kwajalein' => 'Pacific_Marshall',
517
518
		// No DST
519
		'Pacific/Marquesas' => 'Pacific_Marquesas',
520
521
		// No DST
522
		'Pacific/Nauru' => 'Pacific_Nauru',
523
524
		// No DST
525
		'Pacific/Niue' => 'Pacific_Niue',
526
527
		// No DST
528
		'Pacific/Norfolk' => 'Pacific_Norfolk',
529
530
		// No DST
531
		'Pacific/Noumea' => 'Pacific_New_Caledonia',
532
533
		// No DST
534
		'Pacific/Pago_Pago' => 'Pacific_Samoa',
535
536
		// No DST
537
		'Pacific/Palau' => 'Pacific_Palau',
538
539
		// No DST
540
		'Pacific/Pitcairn' => 'Pacific_Pitcairn',
541
542
		// No DST
543
		'Pacific/Pohnpei' => 'Pacific_Pohnpei',
544
545
		// No DST
546
		'Pacific/Port_Moresby' => 'Pacific_Papua_New_Guinea',
547
548
		// No DST
549
		'Pacific/Rarotonga' => 'Pacific_Cook',
550
551
		// No DST
552
		'Pacific/Tahiti' => 'Pacific_Tahiti',
553
554
		// No DST
555
		'Pacific/Tarawa' => 'Pacific_Gilbert',
556
557
		// No DST
558
		'Pacific/Tongatapu' => 'Pacific_Tonga',
559
560
		// No DST
561
		'Pacific/Wake' => 'Pacific_Wake',
562
563
		// No DST
564
		'Pacific/Wallis' => 'Pacific_Wallis',
565
	);
566
567
	call_integration_hook('integrate_metazones', array(&$tzid_metazones, $when));
568
569
	// Fallbacks in case the server has an old version of the TZDB.
570
	$tzids = array_keys($tzid_metazones);
571
	$tzid_fallbacks = get_tzid_fallbacks($tzids, $when);
572
	foreach ($tzid_fallbacks as $orig_tzid => $alt_tzid)
573
	{
574
		// Skip any that are unchanged.
575
		if ($orig_tzid == $alt_tzid)
576
			continue;
577
578
		// Use fallback where possible.
579
		if (!empty($alt_tzid))
580
		{
581
			$tzid_metazones[$alt_tzid] = $tzid_metazones[$orig_tzid];
582
			$txt[$alt_tzid] = $txt[$orig_tzid];
583
		}
584
585
		// Either way, get rid of the unknown time zone.
586
		unset($tzid_metazones[$orig_tzid]);
587
	}
588
589
	return $tzid_metazones;
590
}
591
592
/**
593
 * Returns an array of all the time zones in a country, ranked according
594
 * to population and/or political significance.
595
 *
596
 * @param string $country_code The two-character ISO-3166 code for a country.
597
 * @param string $when The date/time used to determine fallback values.
598
 *		May be a Unix timestamp or any string that strtotime() can understand.
599
 *		Defaults to 'now'.
600
 * @return array An array relating time zones to "meta-zones"
601
 */
602
function get_sorted_tzids_for_country($country_code, $when = 'now')
603
{
604
	static $country_tzids = array();
605
606
	/*
607
		This array lists all the individual time zones in each country,
608
		sorted by population (as reported in statistics available on
609
		Wikipedia in November 2020). Sorting this way enables us to
610
		consistently select the most appropriate individual time zone to
611
		represent all others that share its DST transition rules and values.
612
		For example, this ensures that New York will be preferred over
613
		random small towns in Indiana.
614
615
		If future versions of the time zone database add new time zone
616
		identifiers beyond those included here, they should be added to this
617
		list as appropriate. However, SMF will gracefully handle unexpected
618
		new time zones, so nothing will break in the meantime.
619
	 */
620
	$sorted_tzids = array(
621
		// '??' means international.
622
		'??' => array(
623
			'UTC',
624
		),
625
		'AD' => array(
626
			'Europe/Andorra',
627
		),
628
		'AE' => array(
629
			'Asia/Dubai',
630
		),
631
		'AF' => array(
632
			'Asia/Kabul',
633
		),
634
		'AG' => array(
635
			'America/Antigua',
636
		),
637
		'AI' => array(
638
			'America/Anguilla',
639
		),
640
		'AL' => array(
641
			'Europe/Tirane',
642
		),
643
		'AM' => array(
644
			'Asia/Yerevan',
645
		),
646
		'AO' => array(
647
			'Africa/Luanda',
648
		),
649
		'AQ' => array(
650
			// Sorted based on summer population.
651
			'Antarctica/McMurdo',
652
			'Antarctica/Casey',
653
			'Antarctica/Davis',
654
			'Antarctica/Mawson',
655
			'Antarctica/Rothera',
656
			'Antarctica/Syowa',
657
			'Antarctica/Palmer',
658
			'Antarctica/Troll',
659
			'Antarctica/DumontDUrville',
660
			'Antarctica/Vostok',
661
		),
662
		'AR' => array(
663
			'America/Argentina/Buenos_Aires',
664
			'America/Argentina/Cordoba',
665
			'America/Argentina/Tucuman',
666
			'America/Argentina/Salta',
667
			'America/Argentina/Jujuy',
668
			'America/Argentina/La_Rioja',
669
			'America/Argentina/San_Luis',
670
			'America/Argentina/Catamarca',
671
			'America/Argentina/Mendoza',
672
			'America/Argentina/San_Juan',
673
			'America/Argentina/Rio_Gallegos',
674
			'America/Argentina/Ushuaia',
675
		),
676
		'AS' => array(
677
			'Pacific/Pago_Pago',
678
		),
679
		'AT' => array(
680
			'Europe/Vienna',
681
		),
682
		'AU' => array(
683
			'Australia/Sydney',
684
			'Australia/Melbourne',
685
			'Australia/Brisbane',
686
			'Australia/Perth',
687
			'Australia/Adelaide',
688
			'Australia/Hobart',
689
			'Australia/Darwin',
690
			'Australia/Broken_Hill',
691
			'Australia/Currie',
692
			'Australia/Lord_Howe',
693
			'Australia/Eucla',
694
			'Australia/Lindeman',
695
			'Antarctica/Macquarie',
696
		),
697
		'AW' => array(
698
			'America/Aruba',
699
		),
700
		'AX' => array(
701
			'Europe/Mariehamn',
702
		),
703
		'AZ' => array(
704
			'Asia/Baku',
705
		),
706
		'BA' => array(
707
			'Europe/Sarajevo',
708
		),
709
		'BB' => array(
710
			'America/Barbados',
711
		),
712
		'BD' => array(
713
			'Asia/Dhaka',
714
		),
715
		'BE' => array(
716
			'Europe/Brussels',
717
		),
718
		'BF' => array(
719
			'Africa/Ouagadougou',
720
		),
721
		'BG' => array(
722
			'Europe/Sofia',
723
		),
724
		'BH' => array(
725
			'Asia/Bahrain',
726
		),
727
		'BI' => array(
728
			'Africa/Bujumbura',
729
		),
730
		'BJ' => array(
731
			'Africa/Porto-Novo',
732
		),
733
		'BL' => array(
734
			'America/St_Barthelemy',
735
		),
736
		'BM' => array(
737
			'Atlantic/Bermuda',
738
		),
739
		'BN' => array(
740
			'Asia/Brunei',
741
		),
742
		'BO' => array(
743
			'America/La_Paz',
744
		),
745
		'BQ' => array(
746
			'America/Kralendijk',
747
		),
748
		'BR' => array(
749
			'America/Sao_Paulo',
750
			'America/Bahia',
751
			'America/Fortaleza',
752
			'America/Manaus',
753
			'America/Recife',
754
			'America/Belem',
755
			'America/Maceio',
756
			'America/Campo_Grande',
757
			'America/Cuiaba',
758
			'America/Porto_Velho',
759
			'America/Rio_Branco',
760
			'America/Boa_Vista',
761
			'America/Santarem',
762
			'America/Araguaina',
763
			'America/Eirunepe',
764
			'America/Noronha',
765
		),
766
		'BS' => array(
767
			'America/Nassau',
768
		),
769
		'BT' => array(
770
			'Asia/Thimphu',
771
		),
772
		'BW' => array(
773
			'Africa/Gaborone',
774
		),
775
		'BY' => array(
776
			'Europe/Minsk',
777
		),
778
		'BZ' => array(
779
			'America/Belize',
780
		),
781
		'CA' => array(
782
			'America/Toronto',
783
			'America/Vancouver',
784
			'America/Edmonton',
785
			'America/Winnipeg',
786
			'America/Halifax',
787
			'America/Regina',
788
			'America/St_Johns',
789
			'America/Moncton',
790
			'America/Thunder_Bay',
791
			'America/Whitehorse',
792
			'America/Glace_Bay',
793
			'America/Yellowknife',
794
			'America/Swift_Current',
795
			'America/Dawson_Creek',
796
			'America/Goose_Bay',
797
			'America/Iqaluit',
798
			'America/Creston',
799
			'America/Fort_Nelson',
800
			'America/Inuvik',
801
			'America/Atikokan',
802
			'America/Rankin_Inlet',
803
			'America/Nipigon',
804
			'America/Cambridge_Bay',
805
			'America/Pangnirtung',
806
			'America/Dawson',
807
			'America/Blanc-Sablon',
808
			'America/Rainy_River',
809
			'America/Resolute',
810
		),
811
		'CC' => array(
812
			'Indian/Cocos',
813
		),
814
		'CD' => array(
815
			'Africa/Kinshasa',
816
			'Africa/Lubumbashi',
817
		),
818
		'CF' => array(
819
			'Africa/Bangui',
820
		),
821
		'CG' => array(
822
			'Africa/Brazzaville',
823
		),
824
		'CH' => array(
825
			'Europe/Zurich',
826
		),
827
		'CI' => array(
828
			'Africa/Abidjan',
829
		),
830
		'CK' => array(
831
			'Pacific/Rarotonga',
832
		),
833
		'CL' => array(
834
			'America/Santiago',
835
			'America/Punta_Arenas',
836
			'Pacific/Easter',
837
		),
838
		'CM' => array(
839
			'Africa/Douala',
840
		),
841
		'CN' => array(
842
			'Asia/Shanghai',
843
			'Asia/Urumqi',
844
		),
845
		'CO' => array(
846
			'America/Bogota',
847
		),
848
		'CR' => array(
849
			'America/Costa_Rica',
850
		),
851
		'CU' => array(
852
			'America/Havana',
853
		),
854
		'CV' => array(
855
			'Atlantic/Cape_Verde',
856
		),
857
		'CW' => array(
858
			'America/Curacao',
859
		),
860
		'CX' => array(
861
			'Indian/Christmas',
862
		),
863
		'CY' => array(
864
			'Asia/Nicosia',
865
			'Asia/Famagusta',
866
		),
867
		'CZ' => array(
868
			'Europe/Prague',
869
		),
870
		'DE' => array(
871
			'Europe/Berlin',
872
			'Europe/Busingen',
873
		),
874
		'DJ' => array(
875
			'Africa/Djibouti',
876
		),
877
		'DK' => array(
878
			'Europe/Copenhagen',
879
		),
880
		'DM' => array(
881
			'America/Dominica',
882
		),
883
		'DO' => array(
884
			'America/Santo_Domingo',
885
		),
886
		'DZ' => array(
887
			'Africa/Algiers',
888
		),
889
		'EC' => array(
890
			'America/Guayaquil',
891
			'Pacific/Galapagos',
892
		),
893
		'EE' => array(
894
			'Europe/Tallinn',
895
		),
896
		'EG' => array(
897
			'Africa/Cairo',
898
		),
899
		'EH' => array(
900
			'Africa/El_Aaiun',
901
		),
902
		'ER' => array(
903
			'Africa/Asmara',
904
		),
905
		'ES' => array(
906
			'Europe/Madrid',
907
			'Atlantic/Canary',
908
			'Africa/Ceuta',
909
		),
910
		'ET' => array(
911
			'Africa/Addis_Ababa',
912
		),
913
		'FI' => array(
914
			'Europe/Helsinki',
915
		),
916
		'FJ' => array(
917
			'Pacific/Fiji',
918
		),
919
		'FK' => array(
920
			'Atlantic/Stanley',
921
		),
922
		'FM' => array(
923
			'Pacific/Chuuk',
924
			'Pacific/Kosrae',
925
			'Pacific/Pohnpei',
926
		),
927
		'FO' => array(
928
			'Atlantic/Faroe',
929
		),
930
		'FR' => array(
931
			'Europe/Paris',
932
		),
933
		'GA' => array(
934
			'Africa/Libreville',
935
		),
936
		'GB' => array(
937
			'Europe/London',
938
		),
939
		'GD' => array(
940
			'America/Grenada',
941
		),
942
		'GE' => array(
943
			'Asia/Tbilisi',
944
		),
945
		'GF' => array(
946
			'America/Cayenne',
947
		),
948
		'GG' => array(
949
			'Europe/Guernsey',
950
		),
951
		'GH' => array(
952
			'Africa/Accra',
953
		),
954
		'GI' => array(
955
			'Europe/Gibraltar',
956
		),
957
		'GL' => array(
958
			'America/Nuuk',
959
			'America/Thule',
960
			'America/Scoresbysund',
961
			'America/Danmarkshavn',
962
		),
963
		'GM' => array(
964
			'Africa/Banjul',
965
		),
966
		'GN' => array(
967
			'Africa/Conakry',
968
		),
969
		'GP' => array(
970
			'America/Guadeloupe',
971
		),
972
		'GQ' => array(
973
			'Africa/Malabo',
974
		),
975
		'GR' => array(
976
			'Europe/Athens',
977
		),
978
		'GS' => array(
979
			'Atlantic/South_Georgia',
980
		),
981
		'GT' => array(
982
			'America/Guatemala',
983
		),
984
		'GU' => array(
985
			'Pacific/Guam',
986
		),
987
		'GW' => array(
988
			'Africa/Bissau',
989
		),
990
		'GY' => array(
991
			'America/Guyana',
992
		),
993
		'HK' => array(
994
			'Asia/Hong_Kong',
995
		),
996
		'HN' => array(
997
			'America/Tegucigalpa',
998
		),
999
		'HR' => array(
1000
			'Europe/Zagreb',
1001
		),
1002
		'HT' => array(
1003
			'America/Port-au-Prince',
1004
		),
1005
		'HU' => array(
1006
			'Europe/Budapest',
1007
		),
1008
		'ID' => array(
1009
			'Asia/Jakarta',
1010
			'Asia/Makassar',
1011
			'Asia/Pontianak',
1012
			'Asia/Jayapura',
1013
		),
1014
		'IE' => array(
1015
			'Europe/Dublin',
1016
		),
1017
		'IL' => array(
1018
			'Asia/Jerusalem',
1019
		),
1020
		'IM' => array(
1021
			'Europe/Isle_of_Man',
1022
		),
1023
		'IN' => array(
1024
			'Asia/Kolkata',
1025
		),
1026
		'IO' => array(
1027
			'Indian/Chagos',
1028
		),
1029
		'IQ' => array(
1030
			'Asia/Baghdad',
1031
		),
1032
		'IR' => array(
1033
			'Asia/Tehran',
1034
		),
1035
		'IS' => array(
1036
			'Atlantic/Reykjavik',
1037
		),
1038
		'IT' => array(
1039
			'Europe/Rome',
1040
		),
1041
		'JE' => array(
1042
			'Europe/Jersey',
1043
		),
1044
		'JM' => array(
1045
			'America/Jamaica',
1046
		),
1047
		'JO' => array(
1048
			'Asia/Amman',
1049
		),
1050
		'JP' => array(
1051
			'Asia/Tokyo',
1052
		),
1053
		'KE' => array(
1054
			'Africa/Nairobi',
1055
		),
1056
		'KG' => array(
1057
			'Asia/Bishkek',
1058
		),
1059
		'KH' => array(
1060
			'Asia/Phnom_Penh',
1061
		),
1062
		'KI' => array(
1063
			'Pacific/Tarawa',
1064
			'Pacific/Kiritimati',
1065
			'Pacific/Enderbury',
1066
		),
1067
		'KM' => array(
1068
			'Indian/Comoro',
1069
		),
1070
		'KN' => array(
1071
			'America/St_Kitts',
1072
		),
1073
		'KP' => array(
1074
			'Asia/Pyongyang',
1075
		),
1076
		'KR' => array(
1077
			'Asia/Seoul',
1078
		),
1079
		'KW' => array(
1080
			'Asia/Kuwait',
1081
		),
1082
		'KY' => array(
1083
			'America/Cayman',
1084
		),
1085
		'KZ' => array(
1086
			'Asia/Almaty',
1087
			'Asia/Aqtobe',
1088
			'Asia/Atyrau',
1089
			'Asia/Qostanay',
1090
			'Asia/Qyzylorda',
1091
			'Asia/Aqtau',
1092
			'Asia/Oral',
1093
		),
1094
		'LA' => array(
1095
			'Asia/Vientiane',
1096
		),
1097
		'LB' => array(
1098
			'Asia/Beirut',
1099
		),
1100
		'LC' => array(
1101
			'America/St_Lucia',
1102
		),
1103
		'LI' => array(
1104
			'Europe/Vaduz',
1105
		),
1106
		'LK' => array(
1107
			'Asia/Colombo',
1108
		),
1109
		'LR' => array(
1110
			'Africa/Monrovia',
1111
		),
1112
		'LS' => array(
1113
			'Africa/Maseru',
1114
		),
1115
		'LT' => array(
1116
			'Europe/Vilnius',
1117
		),
1118
		'LU' => array(
1119
			'Europe/Luxembourg',
1120
		),
1121
		'LV' => array(
1122
			'Europe/Riga',
1123
		),
1124
		'LY' => array(
1125
			'Africa/Tripoli',
1126
		),
1127
		'MA' => array(
1128
			'Africa/Casablanca',
1129
		),
1130
		'MC' => array(
1131
			'Europe/Monaco',
1132
		),
1133
		'MD' => array(
1134
			'Europe/Chisinau',
1135
		),
1136
		'ME' => array(
1137
			'Europe/Podgorica',
1138
		),
1139
		'MF' => array(
1140
			'America/Marigot',
1141
		),
1142
		'MG' => array(
1143
			'Indian/Antananarivo',
1144
		),
1145
		'MH' => array(
1146
			'Pacific/Majuro',
1147
			'Pacific/Kwajalein',
1148
		),
1149
		'MK' => array(
1150
			'Europe/Skopje',
1151
		),
1152
		'ML' => array(
1153
			'Africa/Bamako',
1154
		),
1155
		'MM' => array(
1156
			'Asia/Yangon',
1157
		),
1158
		'MN' => array(
1159
			'Asia/Ulaanbaatar',
1160
			'Asia/Choibalsan',
1161
			'Asia/Hovd',
1162
		),
1163
		'MO' => array(
1164
			'Asia/Macau',
1165
		),
1166
		'MP' => array(
1167
			'Pacific/Saipan',
1168
		),
1169
		'MQ' => array(
1170
			'America/Martinique',
1171
		),
1172
		'MR' => array(
1173
			'Africa/Nouakchott',
1174
		),
1175
		'MS' => array(
1176
			'America/Montserrat',
1177
		),
1178
		'MT' => array(
1179
			'Europe/Malta',
1180
		),
1181
		'MU' => array(
1182
			'Indian/Mauritius',
1183
		),
1184
		'MV' => array(
1185
			'Indian/Maldives',
1186
		),
1187
		'MW' => array(
1188
			'Africa/Blantyre',
1189
		),
1190
		'MX' => array(
1191
			'America/Mexico_City',
1192
			'America/Tijuana',
1193
			'America/Monterrey',
1194
			'America/Chihuahua',
1195
			'America/Merida',
1196
			'America/Hermosillo',
1197
			'America/Cancun',
1198
			'America/Matamoros',
1199
			'America/Mazatlan',
1200
			'America/Bahia_Banderas',
1201
			'America/Ojinaga',
1202
		),
1203
		'MY' => array(
1204
			'Asia/Kuala_Lumpur',
1205
			'Asia/Kuching',
1206
		),
1207
		'MZ' => array(
1208
			'Africa/Maputo',
1209
		),
1210
		'NA' => array(
1211
			'Africa/Windhoek',
1212
		),
1213
		'NC' => array(
1214
			'Pacific/Noumea',
1215
		),
1216
		'NE' => array(
1217
			'Africa/Niamey',
1218
		),
1219
		'NF' => array(
1220
			'Pacific/Norfolk',
1221
		),
1222
		'NG' => array(
1223
			'Africa/Lagos',
1224
		),
1225
		'NI' => array(
1226
			'America/Managua',
1227
		),
1228
		'NL' => array(
1229
			'Europe/Amsterdam',
1230
		),
1231
		'NO' => array(
1232
			'Europe/Oslo',
1233
		),
1234
		'NP' => array(
1235
			'Asia/Kathmandu',
1236
		),
1237
		'NR' => array(
1238
			'Pacific/Nauru',
1239
		),
1240
		'NU' => array(
1241
			'Pacific/Niue',
1242
		),
1243
		'NZ' => array(
1244
			'Pacific/Auckland',
1245
			'Pacific/Chatham',
1246
		),
1247
		'OM' => array(
1248
			'Asia/Muscat',
1249
		),
1250
		'PA' => array(
1251
			'America/Panama',
1252
		),
1253
		'PE' => array(
1254
			'America/Lima',
1255
		),
1256
		'PF' => array(
1257
			'Pacific/Tahiti',
1258
			'Pacific/Marquesas',
1259
			'Pacific/Gambier',
1260
		),
1261
		'PG' => array(
1262
			'Pacific/Port_Moresby',
1263
			'Pacific/Bougainville',
1264
		),
1265
		'PH' => array(
1266
			'Asia/Manila',
1267
		),
1268
		'PK' => array(
1269
			'Asia/Karachi',
1270
		),
1271
		'PL' => array(
1272
			'Europe/Warsaw',
1273
		),
1274
		'PM' => array(
1275
			'America/Miquelon',
1276
		),
1277
		'PN' => array(
1278
			'Pacific/Pitcairn',
1279
		),
1280
		'PR' => array(
1281
			'America/Puerto_Rico',
1282
		),
1283
		'PS' => array(
1284
			'Asia/Gaza',
1285
			'Asia/Hebron',
1286
		),
1287
		'PT' => array(
1288
			'Europe/Lisbon',
1289
			'Atlantic/Madeira',
1290
			'Atlantic/Azores',
1291
		),
1292
		'PW' => array(
1293
			'Pacific/Palau',
1294
		),
1295
		'PY' => array(
1296
			'America/Asuncion',
1297
		),
1298
		'QA' => array(
1299
			'Asia/Qatar',
1300
		),
1301
		'RE' => array(
1302
			'Indian/Reunion',
1303
		),
1304
		'RO' => array(
1305
			'Europe/Bucharest',
1306
		),
1307
		'RS' => array(
1308
			'Europe/Belgrade',
1309
		),
1310
		'RU' => array(
1311
			'Europe/Moscow',
1312
			'Asia/Novosibirsk',
1313
			'Asia/Yekaterinburg',
1314
			'Europe/Samara',
1315
			'Asia/Omsk',
1316
			'Asia/Krasnoyarsk',
1317
			'Europe/Volgograd',
1318
			'Europe/Saratov',
1319
			'Asia/Barnaul',
1320
			'Europe/Ulyanovsk',
1321
			'Asia/Irkutsk',
1322
			'Asia/Vladivostok',
1323
			'Asia/Tomsk',
1324
			'Asia/Novokuznetsk',
1325
			'Europe/Astrakhan',
1326
			'Europe/Kirov',
1327
			'Europe/Kaliningrad',
1328
			'Asia/Chita',
1329
			'Asia/Yakutsk',
1330
			'Asia/Sakhalin',
1331
			'Asia/Kamchatka',
1332
			'Asia/Magadan',
1333
			'Asia/Anadyr',
1334
			'Asia/Khandyga',
1335
			'Asia/Ust-Nera',
1336
			'Asia/Srednekolymsk',
1337
		),
1338
		'RW' => array(
1339
			'Africa/Kigali',
1340
		),
1341
		'SA' => array(
1342
			'Asia/Riyadh',
1343
		),
1344
		'SB' => array(
1345
			'Pacific/Guadalcanal',
1346
		),
1347
		'SC' => array(
1348
			'Indian/Mahe',
1349
		),
1350
		'SD' => array(
1351
			'Africa/Khartoum',
1352
		),
1353
		'SE' => array(
1354
			'Europe/Stockholm',
1355
		),
1356
		'SG' => array(
1357
			'Asia/Singapore',
1358
		),
1359
		'SH' => array(
1360
			'Atlantic/St_Helena',
1361
		),
1362
		'SI' => array(
1363
			'Europe/Ljubljana',
1364
		),
1365
		'SJ' => array(
1366
			'Arctic/Longyearbyen',
1367
		),
1368
		'SK' => array(
1369
			'Europe/Bratislava',
1370
		),
1371
		'SL' => array(
1372
			'Africa/Freetown',
1373
		),
1374
		'SM' => array(
1375
			'Europe/San_Marino',
1376
		),
1377
		'SN' => array(
1378
			'Africa/Dakar',
1379
		),
1380
		'SO' => array(
1381
			'Africa/Mogadishu',
1382
		),
1383
		'SR' => array(
1384
			'America/Paramaribo',
1385
		),
1386
		'SS' => array(
1387
			'Africa/Juba',
1388
		),
1389
		'ST' => array(
1390
			'Africa/Sao_Tome',
1391
		),
1392
		'SV' => array(
1393
			'America/El_Salvador',
1394
		),
1395
		'SX' => array(
1396
			'America/Lower_Princes',
1397
		),
1398
		'SY' => array(
1399
			'Asia/Damascus',
1400
		),
1401
		'SZ' => array(
1402
			'Africa/Mbabane',
1403
		),
1404
		'TC' => array(
1405
			'America/Grand_Turk',
1406
		),
1407
		'TD' => array(
1408
			'Africa/Ndjamena',
1409
		),
1410
		'TF' => array(
1411
			'Indian/Kerguelen',
1412
		),
1413
		'TG' => array(
1414
			'Africa/Lome',
1415
		),
1416
		'TH' => array(
1417
			'Asia/Bangkok',
1418
		),
1419
		'TJ' => array(
1420
			'Asia/Dushanbe',
1421
		),
1422
		'TK' => array(
1423
			'Pacific/Fakaofo',
1424
		),
1425
		'TL' => array(
1426
			'Asia/Dili',
1427
		),
1428
		'TM' => array(
1429
			'Asia/Ashgabat',
1430
		),
1431
		'TN' => array(
1432
			'Africa/Tunis',
1433
		),
1434
		'TO' => array(
1435
			'Pacific/Tongatapu',
1436
		),
1437
		'TR' => array(
1438
			'Europe/Istanbul',
1439
		),
1440
		'TT' => array(
1441
			'America/Port_of_Spain',
1442
		),
1443
		'TV' => array(
1444
			'Pacific/Funafuti',
1445
		),
1446
		'TW' => array(
1447
			'Asia/Taipei',
1448
		),
1449
		'TZ' => array(
1450
			'Africa/Dar_es_Salaam',
1451
		),
1452
		'UA' => array(
1453
			'Europe/Kiev',
1454
			'Europe/Zaporozhye',
1455
			'Europe/Simferopol',
1456
			'Europe/Uzhgorod',
1457
		),
1458
		'UG' => array(
1459
			'Africa/Kampala',
1460
		),
1461
		'UM' => array(
1462
			'Pacific/Midway',
1463
			'Pacific/Wake',
1464
		),
1465
		'US' => array(
1466
			'America/New_York',
1467
			'America/Los_Angeles',
1468
			'America/Chicago',
1469
			'America/Denver',
1470
			'America/Phoenix',
1471
			'America/Indiana/Indianapolis',
1472
			'America/Detroit',
1473
			'America/Kentucky/Louisville',
1474
			'Pacific/Honolulu',
1475
			'America/Anchorage',
1476
			'America/Boise',
1477
			'America/Juneau',
1478
			'America/Indiana/Vincennes',
1479
			'America/Sitka',
1480
			'America/Menominee',
1481
			'America/Indiana/Tell_City',
1482
			'America/Kentucky/Monticello',
1483
			'America/Nome',
1484
			'America/Indiana/Knox',
1485
			'America/North_Dakota/Beulah',
1486
			'America/Indiana/Winamac',
1487
			'America/Indiana/Petersburg',
1488
			'America/Indiana/Vevay',
1489
			'America/Metlakatla',
1490
			'America/North_Dakota/New_Salem',
1491
			'America/Indiana/Marengo',
1492
			'America/Yakutat',
1493
			'America/North_Dakota/Center',
1494
			'America/Adak',
1495
		),
1496
		'UY' => array(
1497
			'America/Montevideo',
1498
		),
1499
		'UZ' => array(
1500
			'Asia/Tashkent',
1501
			'Asia/Samarkand',
1502
		),
1503
		'VA' => array(
1504
			'Europe/Vatican',
1505
		),
1506
		'VC' => array(
1507
			'America/St_Vincent',
1508
		),
1509
		'VE' => array(
1510
			'America/Caracas',
1511
		),
1512
		'VG' => array(
1513
			'America/Tortola',
1514
		),
1515
		'VI' => array(
1516
			'America/St_Thomas',
1517
		),
1518
		'VN' => array(
1519
			'Asia/Ho_Chi_Minh',
1520
		),
1521
		'VU' => array(
1522
			'Pacific/Efate',
1523
		),
1524
		'WF' => array(
1525
			'Pacific/Wallis',
1526
		),
1527
		'WS' => array(
1528
			'Pacific/Apia',
1529
		),
1530
		'YE' => array(
1531
			'Asia/Aden',
1532
		),
1533
		'YT' => array(
1534
			'Indian/Mayotte',
1535
		),
1536
		'ZA' => array(
1537
			'Africa/Johannesburg',
1538
		),
1539
		'ZM' => array(
1540
			'Africa/Lusaka',
1541
		),
1542
		'ZW' => array(
1543
			'Africa/Harare',
1544
		),
1545
	);
1546
1547
	if (!isset($country_tzids[$country_code]))
1548
	{
1549
		call_integration_hook('integrate_country_timezones', array(&$sorted_tzids, $country_code, $when));
1550
1551
		$country_tzids[$country_code] = isset($sorted_tzids[$country_code]) ? $sorted_tzids[$country_code] : array();
1552
1553
		// Make sure that no time zones are missing.
1554
		$country_tzids[$country_code] = array_unique(array_merge($country_tzids[$country_code], array_intersect(@timezone_identifiers_list(DateTimeZone::PER_COUNTRY, $country_code), timezone_identifiers_list())));
0 ignored issues
show
Bug introduced by
It seems like @timezone_identifiers_li...COUNTRY, $country_code) can also be of type false; however, parameter $array1 of array_intersect() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1554
		$country_tzids[$country_code] = array_unique(array_merge($country_tzids[$country_code], array_intersect(/** @scrutinizer ignore-type */ @timezone_identifiers_list(DateTimeZone::PER_COUNTRY, $country_code), timezone_identifiers_list())));
Loading history...
Bug introduced by
It seems like timezone_identifiers_list() can also be of type false; however, parameter $array2 of array_intersect() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1554
		$country_tzids[$country_code] = array_unique(array_merge($country_tzids[$country_code], array_intersect(@timezone_identifiers_list(DateTimeZone::PER_COUNTRY, $country_code), /** @scrutinizer ignore-type */ timezone_identifiers_list())));
Loading history...
1555
1556
		// Get fallbacks where necessary.
1557
		$country_tzids[$country_code] = array_values(get_tzid_fallbacks($country_tzids[$country_code], $when));
1558
1559
		// Filter out any time zones that are still undefined.
1560
		$country_tzids[$country_code] = array_intersect(array_filter($country_tzids[$country_code]), timezone_identifiers_list(DateTimeZone::ALL_WITH_BC));
1561
	}
1562
1563
	return $country_tzids[$country_code];
1564
}
1565
1566
/**
1567
 * Checks a list of time zone identifiers to make sure they are all defined in
1568
 * the installed version of the time zone database, and returns an array of
1569
 * key-value substitution pairs.
1570
 *
1571
 * For defined time zone identifiers, the substitution value will be identical
1572
 * to the original value. For undefined ones, the substitute will be a time zone
1573
 * identifier that was equivalent to the missing one at the specified time, or
1574
 * an empty string if there was no equivalent at that time.
1575
 *
1576
 * Note: These fallbacks do not need to include every new time zone ever. They
1577
 * only need to cover any that are used in $tzid_metazones.
1578
 *
1579
 * To find the date & time when a new time zone comes into effect, check
1580
 * the TZDB changelog at https://data.iana.org/time-zones/tzdb/NEWS
1581
 *
1582
 * @param array $tzids The time zone identifiers to check.
1583
 * @param string $when The date/time used to determine substitute values.
1584
 *		May be a Unix timestamp or any string that strtotime() can understand.
1585
 *		Defaults to 'now'.
1586
 * @return array Substitute values for any missing time zone identifiers.
1587
 */
1588
function get_tzid_fallbacks($tzids, $when = 'now')
1589
{
1590
	$tzids = (array) $tzids;
1591
1592
	$when = is_numeric($when) ? intval($when) : (is_int(@strtotime($when)) ? strtotime($when) : time());
0 ignored issues
show
introduced by
The condition is_int(@strtotime($when)) is always true.
Loading history...
1593
1594
	// 'ts' is the timestamp when the substitution first becomes valid.
1595
	// 'tzid' is the alternative time zone identifier to use.
1596
	$fallbacks = array(
1597
		// 1. Simple renames. PHP_INT_MIN because these are valid for all dates.
1598
		'Asia/Kolkata' => array(
1599
			array(
1600
				'ts' => PHP_INT_MIN,
1601
				'tzid' => 'Asia/Calcutta',
1602
			),
1603
		),
1604
		'Pacific/Chuuk' => array(
1605
			array(
1606
				'ts' => PHP_INT_MIN,
1607
				'tzid' => 'Pacific/Truk',
1608
			),
1609
		),
1610
		'Pacific/Pohnpei' => array(
1611
			array(
1612
				'ts' => PHP_INT_MIN,
1613
				'tzid' => 'Pacific/Ponape',
1614
			),
1615
		),
1616
		'Asia/Yangon' => array(
1617
			array(
1618
				'ts' => PHP_INT_MIN,
1619
				'tzid' => 'Asia/Rangoon',
1620
			),
1621
		),
1622
		'America/Nuuk' => array(
1623
			array(
1624
				'ts' => PHP_INT_MIN,
1625
				'tzid' => 'America/Godthab',
1626
			),
1627
		),
1628
1629
		// 2. Newly created time zones.
1630
1631
		// The same as Tasmania, except it stayed on DST all year in 2010.
1632
		// Australia/Tasmania is an otherwise unused backwards compatibility
1633
		// link to Australia/Hobart, so we can borrow it here without conflict.
1634
		'Antarctica/Macquarie' => array(
1635
			array(
1636
				'ts' => PHP_INT_MIN,
1637
				'tzid' => 'Australia/Tasmania',
1638
			),
1639
			array(
1640
				'ts' => strtotime('2010-04-03T16:00:00+0000'),
1641
				'tzid' => 'Etc/GMT-11',
1642
			),
1643
			array(
1644
				'ts' => strtotime('2011-04-07T17:00:00+0000'),
1645
				'tzid' => 'Australia/Tasmania',
1646
			),
1647
		),
1648
1649
		// This place uses two hours for DST. No substitutes are possible.
1650
		'Antarctica/Troll' => array(
1651
			array(
1652
				'ts' => PHP_INT_MIN,
1653
				'tzid' => '',
1654
			),
1655
		),
1656
1657
		// Diverged from Pacific/Port_Moresby in version 2014i.
1658
		'Pacific/Bougainville' => array(
1659
			// Before the divergence, we don't actually need this one at all.
1660
			array(
1661
				'ts' => PHP_INT_MIN,
1662
				'tzid' => '',
1663
			),
1664
			// For dates after divergence, it is the same as Pacific/Kosrae.
1665
			// If this ever ceases to be true, add another entry.
1666
			array(
1667
				'ts' => strtotime('2014-12-27T16:00:00+0000'),
1668
				'tzid' => 'Pacific/Kosrae',
1669
			),
1670
		),
1671
1672
		// Diverged from America/Santiago in version 2017a.
1673
		'America/Punta_Arenas' => array(
1674
			// Before the divergence, we don't actually need this one at all.
1675
			array(
1676
				'ts' => PHP_INT_MIN,
1677
				'tzid' => '',
1678
			),
1679
			// For dates after divergence, it is the same as Antarctica/Palmer.
1680
			// If this ever ceases to be true, add another entry.
1681
			array(
1682
				'ts' => strtotime('2017-05-14T03:00:00+0000'),
1683
				'tzid' => 'Antarctica/Palmer',
1684
			),
1685
		),
1686
	);
1687
1688
	$missing = array_diff($tzids, timezone_identifiers_list(DateTimeZone::ALL_WITH_BC));
0 ignored issues
show
Bug introduced by
It seems like timezone_identifiers_lis...eTimeZone::ALL_WITH_BC) can also be of type false; however, parameter $array2 of array_diff() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1688
	$missing = array_diff($tzids, /** @scrutinizer ignore-type */ timezone_identifiers_list(DateTimeZone::ALL_WITH_BC));
Loading history...
1689
1690
	call_integration_hook('integrate_timezone_fallbacks', array(&$fallbacks, &$missing, $tzids, $when));
1691
1692
	$replacements = array();
1693
1694
	foreach ($tzids as $tzid)
1695
	{
1696
		// Not missing.
1697
		if (!in_array($tzid, $missing))
1698
			$replacements[$tzid] = $tzid;
1699
1700
		// Missing and we have no fallback.
1701
		elseif (empty($fallbacks[$tzid]))
1702
			$replacements[$tzid] = '';
1703
1704
		// Missing, but we have a fallback.
1705
		else
1706
		{
1707
			usort($fallbacks[$tzid], function ($a, $b) {
1708
				return $a['ts'] > $b['ts'];
1709
			});
1710
1711
			foreach ($fallbacks[$tzid] as $alt)
1712
			{
1713
				if ($when < $alt['ts'])
1714
					break;
1715
1716
				$replacements[$tzid] = $alt['tzid'];
1717
			}
1718
1719
			if (empty($replacements[$tzid]))
1720
				$replacements[$tzid] = '';
1721
		}
1722
	}
1723
1724
	return $replacements;
1725
}
1726
1727
?>