1#[cfg(any(test, target_os = "android"))]
4use std::ffi::CStr;
5
6#[cfg(any(test, target_vendor = "apple", target_env = "ohos"))]
8pub(crate) mod buffer {
9 pub const MAX_LEN: usize = 64;
11
12 pub const fn tzname_buf() -> [u8; MAX_LEN] {
16 [0; MAX_LEN]
17 }
18}
19
20#[cfg(any(test, target_os = "android"))]
32const ANDROID_TIMEZONE_PROPERTY_NAME: &[u8] = b"persist.sys.timezone\0";
33
34#[cfg(any(test, target_os = "android"))]
37pub(crate) fn android_timezone_property_name() -> &'static CStr {
38 if cfg!(any(test, debug_assertions)) {
40 return CStr::from_bytes_with_nul(ANDROID_TIMEZONE_PROPERTY_NAME).unwrap();
41 }
42
43 unsafe { CStr::from_bytes_with_nul_unchecked(ANDROID_TIMEZONE_PROPERTY_NAME) }
46}
47
48#[cfg(test)]
49mod tests {
50 use core::mem::size_of_val;
51 use std::ffi::CStr;
52
53 use super::buffer::{tzname_buf, MAX_LEN};
54 use super::{android_timezone_property_name, ANDROID_TIMEZONE_PROPERTY_NAME};
55
56 #[test]
57 fn test_android_timezone_property_name_is_valid_cstr() {
58 CStr::from_bytes_with_nul(ANDROID_TIMEZONE_PROPERTY_NAME).unwrap();
59
60 let mut invalid_property_name = ANDROID_TIMEZONE_PROPERTY_NAME.to_owned();
61 invalid_property_name.push(b'\0');
62 CStr::from_bytes_with_nul(&invalid_property_name).unwrap_err();
63 }
64
65 #[test]
66 fn test_android_timezone_property_name_getter() {
67 let key = android_timezone_property_name().to_bytes_with_nul();
68 assert_eq!(key, ANDROID_TIMEZONE_PROPERTY_NAME);
69 std::str::from_utf8(key).unwrap();
70 }
71
72 static KNOWN_TIMEZONE_NAMES: &[&str] = &[
79 "Africa/Abidjan",
80 "Africa/Accra",
81 "Africa/Addis_Ababa",
82 "Africa/Algiers",
83 "Africa/Asmara",
84 "Africa/Asmera",
85 "Africa/Bamako",
86 "Africa/Bangui",
87 "Africa/Banjul",
88 "Africa/Bissau",
89 "Africa/Blantyre",
90 "Africa/Brazzaville",
91 "Africa/Bujumbura",
92 "Africa/Cairo",
93 "Africa/Casablanca",
94 "Africa/Conakry",
95 "Africa/Dakar",
96 "Africa/Dar_es_Salaam",
97 "Africa/Djibouti",
98 "Africa/Douala",
99 "Africa/El_Aaiun",
100 "Africa/Freetown",
101 "Africa/Gaborone",
102 "Africa/Harare",
103 "Africa/Johannesburg",
104 "Africa/Juba",
105 "Africa/Kampala",
106 "Africa/Khartoum",
107 "Africa/Kigali",
108 "Africa/Libreville",
109 "Africa/Lome",
110 "Africa/Luanda",
111 "Africa/Lusaka",
112 "Africa/Malabo",
113 "Africa/Maseru",
114 "Africa/Mbabane",
115 "Africa/Mogadishu",
116 "Africa/Monrovia",
117 "Africa/Nairobi",
118 "Africa/Ndjamena",
119 "Africa/Niamey",
120 "Africa/Nouakchott",
121 "Africa/Ouagadougou",
122 "Africa/Porto-Novo",
123 "Africa/Sao_Tome",
124 "Africa/Timbuktu",
125 "Africa/Tripoli",
126 "Africa/Tunis",
127 "Africa/Windhoek",
128 "America/Anguilla",
129 "America/Antigua",
130 "America/Argentina/ComodRivadavia",
131 "America/Aruba",
132 "America/Asuncion",
133 "America/Atka",
134 "America/Barbados",
135 "America/Belize",
136 "America/Bogota",
137 "America/Buenos_Aires",
138 "America/Caracas",
139 "America/Catamarca",
140 "America/Cayenne",
141 "America/Cayman",
142 "America/Coral_Harbour",
143 "America/Cordoba",
144 "America/Costa_Rica",
145 "America/Curacao",
146 "America/Dominica",
147 "America/El_Salvador",
148 "America/Ensenada",
149 "America/Fort_Wayne",
150 "America/Godthab",
151 "America/Grand_Turk",
152 "America/Grenada",
153 "America/Guadeloupe",
154 "America/Guatemala",
155 "America/Guyana",
156 "America/Havana",
157 "America/Indianapolis",
158 "America/Jamaica",
159 "America/Jujuy",
160 "America/Knox_IN",
161 "America/Kralendijk",
162 "America/La_Paz",
163 "America/Lima",
164 "America/Louisville",
165 "America/Lower_Princes",
166 "America/Managua",
167 "America/Marigot",
168 "America/Martinique",
169 "America/Mendoza",
170 "America/Miquelon",
171 "America/Montevideo",
172 "America/Montreal",
173 "America/Montserrat",
174 "America/Nassau",
175 "America/Nipigon",
176 "America/Pangnirtung",
177 "America/Paramaribo",
178 "America/Port-au-Prince",
179 "America/Port_of_Spain",
180 "America/Porto_Acre",
181 "America/Rainy_River",
182 "America/Rosario",
183 "America/Santa_Isabel",
184 "America/Santo_Domingo",
185 "America/Shiprock",
186 "America/St_Barthelemy",
187 "America/St_Kitts",
188 "America/St_Lucia",
189 "America/St_Thomas",
190 "America/St_Vincent",
191 "America/Tegucigalpa",
192 "America/Thunder_Bay",
193 "America/Tortola",
194 "America/Virgin",
195 "America/Yellowknife",
196 "Antarctica/South_Pole",
197 "Arctic/Longyearbyen",
198 "Asia/Aden",
199 "Asia/Amman",
200 "Asia/Ashgabat",
201 "Asia/Ashkhabad",
202 "Asia/Baghdad",
203 "Asia/Bahrain",
204 "Asia/Baku",
205 "Asia/Beirut",
206 "Asia/Bishkek",
207 "Asia/Brunei",
208 "Asia/Calcutta",
209 "Asia/Choibalsan",
210 "Asia/Chongqing",
211 "Asia/Chungking",
212 "Asia/Colombo",
213 "Asia/Dacca",
214 "Asia/Damascus",
215 "Asia/Dhaka",
216 "Asia/Dili",
217 "Asia/Dushanbe",
218 "Asia/Harbin",
219 "Asia/Hong_Kong",
220 "Asia/Istanbul",
221 "Asia/Jerusalem",
222 "Asia/Kabul",
223 "Asia/Karachi",
224 "Asia/Kashgar",
225 "Asia/Kathmandu",
226 "Asia/Katmandu",
227 "Asia/Kolkata",
228 "Asia/Kuwait",
229 "Asia/Macao",
230 "Asia/Macau",
231 "Asia/Manila",
232 "Asia/Muscat",
233 "Asia/Phnom_Penh",
234 "Asia/Pyongyang",
235 "Asia/Qatar",
236 "Asia/Rangoon",
237 "Asia/Saigon",
238 "Asia/Seoul",
239 "Asia/Taipei",
240 "Asia/Tbilisi",
241 "Asia/Tehran",
242 "Asia/Tel_Aviv",
243 "Asia/Thimbu",
244 "Asia/Thimphu",
245 "Asia/Ujung_Pandang",
246 "Asia/Ulan_Bator",
247 "Asia/Vientiane",
248 "Asia/Yangon",
249 "Asia/Yerevan",
250 "Atlantic/Bermuda",
251 "Atlantic/Cape_Verde",
252 "Atlantic/Faeroe",
253 "Atlantic/Faroe",
254 "Atlantic/Jan_Mayen",
255 "Atlantic/Reykjavik",
256 "Atlantic/South_Georgia",
257 "Atlantic/St_Helena",
258 "Atlantic/Stanley",
259 "Australia/ACT",
260 "Australia/Canberra",
261 "Australia/Currie",
262 "Australia/LHI",
263 "Australia/North",
264 "Australia/NSW",
265 "Australia/Queensland",
266 "Australia/South",
267 "Australia/Tasmania",
268 "Australia/Victoria",
269 "Australia/West",
270 "Australia/Yancowinna",
271 "Brazil/Acre",
272 "Brazil/DeNoronha",
273 "Brazil/East",
274 "Brazil/West",
275 "Canada/Atlantic",
276 "Canada/Central",
277 "Canada/Eastern",
278 "Canada/Mountain",
279 "Canada/Newfoundland",
280 "Canada/Pacific",
281 "Canada/Saskatchewan",
282 "Canada/Yukon",
283 "CET",
284 "Chile/Continental",
285 "Chile/EasterIsland",
286 "CST6CDT",
287 "Cuba",
288 "EET",
289 "Egypt",
290 "Eire",
291 "EST",
292 "EST5EDT",
293 "Etc/GMT",
294 "Etc/GMT+0",
295 "Etc/GMT+1",
296 "Etc/GMT+10",
297 "Etc/GMT+11",
298 "Etc/GMT+12",
299 "Etc/GMT+2",
300 "Etc/GMT+3",
301 "Etc/GMT+4",
302 "Etc/GMT+5",
303 "Etc/GMT+6",
304 "Etc/GMT+7",
305 "Etc/GMT+8",
306 "Etc/GMT+9",
307 "Etc/GMT-0",
308 "Etc/GMT-1",
309 "Etc/GMT-10",
310 "Etc/GMT-11",
311 "Etc/GMT-12",
312 "Etc/GMT-13",
313 "Etc/GMT-14",
314 "Etc/GMT-2",
315 "Etc/GMT-3",
316 "Etc/GMT-4",
317 "Etc/GMT-5",
318 "Etc/GMT-6",
319 "Etc/GMT-7",
320 "Etc/GMT-8",
321 "Etc/GMT-9",
322 "Etc/GMT0",
323 "Etc/Greenwich",
324 "Etc/UCT",
325 "Etc/Universal",
326 "Etc/UTC",
327 "Etc/Zulu",
328 "Europe/Amsterdam",
329 "Europe/Andorra",
330 "Europe/Athens",
331 "Europe/Belfast",
332 "Europe/Belgrade",
333 "Europe/Bratislava",
334 "Europe/Brussels",
335 "Europe/Bucharest",
336 "Europe/Budapest",
337 "Europe/Chisinau",
338 "Europe/Copenhagen",
339 "Europe/Dublin",
340 "Europe/Gibraltar",
341 "Europe/Guernsey",
342 "Europe/Helsinki",
343 "Europe/Isle_of_Man",
344 "Europe/Istanbul",
345 "Europe/Jersey",
346 "Europe/Kiev",
347 "Europe/Ljubljana",
348 "Europe/London",
349 "Europe/Luxembourg",
350 "Europe/Malta",
351 "Europe/Mariehamn",
352 "Europe/Minsk",
353 "Europe/Monaco",
354 "Europe/Nicosia",
355 "Europe/Oslo",
356 "Europe/Paris",
357 "Europe/Podgorica",
358 "Europe/Prague",
359 "Europe/Riga",
360 "Europe/Rome",
361 "Europe/San_Marino",
362 "Europe/Sarajevo",
363 "Europe/Skopje",
364 "Europe/Sofia",
365 "Europe/Stockholm",
366 "Europe/Tallinn",
367 "Europe/Tirane",
368 "Europe/Tiraspol",
369 "Europe/Uzhgorod",
370 "Europe/Vaduz",
371 "Europe/Vatican",
372 "Europe/Vienna",
373 "Europe/Vilnius",
374 "Europe/Warsaw",
375 "Europe/Zagreb",
376 "Europe/Zaporozhye",
377 "Factory",
378 "GB",
379 "GB-Eire",
380 "GMT",
381 "GMT+0",
382 "GMT-0",
383 "GMT0",
384 "Greenwich",
385 "Hongkong",
386 "HST",
387 "Iceland",
388 "Indian/Antananarivo",
389 "Indian/Chagos",
390 "Indian/Christmas",
391 "Indian/Cocos",
392 "Indian/Comoro",
393 "Indian/Kerguelen",
394 "Indian/Mahe",
395 "Indian/Mauritius",
396 "Indian/Mayotte",
397 "Indian/Reunion",
398 "Iran",
399 "Israel",
400 "Jamaica",
401 "Japan",
402 "Kwajalein",
403 "Libya",
404 "MET",
405 "Mexico/BajaNorte",
406 "Mexico/BajaSur",
407 "Mexico/General",
408 "MST",
409 "MST7MDT",
410 "Navajo",
411 "NZ",
412 "NZ-CHAT",
413 "Pacific/Apia",
414 "Pacific/Efate",
415 "Pacific/Enderbury",
416 "Pacific/Fakaofo",
417 "Pacific/Fiji",
418 "Pacific/Funafuti",
419 "Pacific/Guam",
420 "Pacific/Johnston",
421 "Pacific/Nauru",
422 "Pacific/Niue",
423 "Pacific/Norfolk",
424 "Pacific/Noumea",
425 "Pacific/Palau",
426 "Pacific/Pitcairn",
427 "Pacific/Ponape",
428 "Pacific/Rarotonga",
429 "Pacific/Saipan",
430 "Pacific/Samoa",
431 "Pacific/Tongatapu",
432 "Pacific/Truk",
433 "Pacific/Wallis",
434 "Pacific/Yap",
435 "Poland",
436 "Portugal",
437 "PRC",
438 "PST8PDT",
439 "ROC",
440 "ROK",
441 "Singapore",
442 "Turkey",
443 "UCT",
444 "Universal",
445 "US/Alaska",
446 "US/Aleutian",
447 "US/Arizona",
448 "US/Central",
449 "US/East-Indiana",
450 "US/Eastern",
451 "US/Hawaii",
452 "US/Indiana-Starke",
453 "US/Michigan",
454 "US/Mountain",
455 "US/Pacific",
456 "US/Samoa",
457 "UTC",
458 "W-SU",
459 "WET",
460 "Zulu",
461 "America/Rio_Branco",
462 "America/Maceio",
463 "America/Metlakatla",
464 "America/Juneau",
465 "America/Sitka",
466 "America/Adak",
467 "America/Yakutat",
468 "America/Anchorage",
469 "America/Nome",
470 "America/Manaus",
471 "America/Eirunepe",
472 "Asia/Aqtobe",
473 "America/Blanc-Sablon",
474 "America/Puerto_Rico",
475 "America/Goose_Bay",
476 "America/Moncton",
477 "America/Glace_Bay",
478 "America/Halifax",
479 "America/Noronha",
480 "Asia/Atyrau",
481 "Atlantic/Azores",
482 "America/Bahia",
483 "America/Bahia_Banderas",
484 "America/Tijuana",
485 "America/Mazatlan",
486 "Asia/Hovd",
487 "Asia/Shanghai",
488 "Asia/Makassar",
489 "Asia/Pontianak",
490 "Pacific/Bougainville",
491 "America/Fortaleza",
492 "America/Sao_Paulo",
493 "America/Argentina/Buenos_Aires",
494 "Europe/Busingen",
495 "Europe/Zurich",
496 "America/Merida",
497 "Atlantic/Canary",
498 "Antarctica/Casey",
499 "America/Argentina/Catamarca",
500 "America/Indiana/Tell_City",
501 "America/Indiana/Knox",
502 "America/Menominee",
503 "America/North_Dakota/Beulah",
504 "America/North_Dakota/New_Salem",
505 "America/North_Dakota/Center",
506 "America/Rankin_Inlet",
507 "America/Resolute",
508 "America/Winnipeg",
509 "America/Chicago",
510 "Africa/Maputo",
511 "America/Mexico_City",
512 "Africa/Ceuta",
513 "Pacific/Chatham",
514 "America/Chihuahua",
515 "America/Ojinaga",
516 "America/Ciudad_Juarez",
517 "Pacific/Chuuk",
518 "America/Matamoros",
519 "Europe/Simferopol",
520 "Asia/Dubai",
521 "America/Swift_Current",
522 "America/Regina",
523 "Antarctica/Davis",
524 "Africa/Lubumbashi",
525 "Africa/Kinshasa",
526 "Antarctica/DumontDUrville",
527 "America/Monterrey",
528 "Pacific/Easter",
529 "America/Indiana/Marengo",
530 "America/Indiana/Vincennes",
531 "America/Indiana/Indianapolis",
532 "America/Indiana/Petersburg",
533 "America/Indiana/Winamac",
534 "America/Indiana/Vevay",
535 "America/Kentucky/Louisville",
536 "America/Kentucky/Monticello",
537 "America/Detroit",
538 "America/Iqaluit",
539 "America/Toronto",
540 "America/New_York",
541 "America/Guayaquil",
542 "America/Atikokan",
543 "America/Panama",
544 "Asia/Tokyo",
545 "Pacific/Galapagos",
546 "Pacific/Gambier",
547 "Asia/Gaza",
548 "Pacific/Tarawa",
549 "Pacific/Honolulu",
550 "Asia/Jakarta",
551 "America/Argentina/Jujuy",
552 "Indian/Maldives",
553 "Pacific/Kosrae",
554 "Pacific/Kwajalein",
555 "America/Argentina/La_Rioja",
556 "Pacific/Kiritimati",
557 "Australia/Lord_Howe",
558 "Antarctica/Macquarie",
559 "Atlantic/Madeira",
560 "Asia/Kuala_Lumpur",
561 "Asia/Aqtau",
562 "Pacific/Marquesas",
563 "America/Cuiaba",
564 "America/Campo_Grande",
565 "Antarctica/Mawson",
566 "America/Argentina/Mendoza",
567 "Pacific/Pago_Pago",
568 "Pacific/Midway",
569 "America/Argentina/Cordoba",
570 "America/Santiago",
571 "Asia/Nicosia",
572 "Europe/Berlin",
573 "America/Nuuk",
574 "Asia/Almaty",
575 "Pacific/Majuro",
576 "Asia/Ulaanbaatar",
577 "Europe/Kyiv",
578 "America/Edmonton",
579 "America/Boise",
580 "America/Inuvik",
581 "America/Cambridge_Bay",
582 "America/Denver",
583 "Europe/Kaliningrad",
584 "Europe/Kirov",
585 "Europe/Moscow",
586 "Europe/Volgograd",
587 "Europe/Astrakhan",
588 "Europe/Samara",
589 "Europe/Saratov",
590 "Europe/Ulyanovsk",
591 "Asia/Yekaterinburg",
592 "Asia/Omsk",
593 "Asia/Barnaul",
594 "Asia/Novokuznetsk",
595 "Asia/Krasnoyarsk",
596 "Asia/Novosibirsk",
597 "Asia/Tomsk",
598 "Asia/Irkutsk",
599 "Asia/Yakutsk",
600 "Asia/Khandyga",
601 "Asia/Chita",
602 "Asia/Vladivostok",
603 "Asia/Ust-Nera",
604 "Asia/Magadan",
605 "Asia/Srednekolymsk",
606 "Asia/Sakhalin",
607 "Asia/Anadyr",
608 "Asia/Kamchatka",
609 "America/Phoenix",
610 "America/Creston",
611 "America/Dawson_Creek",
612 "America/Fort_Nelson",
613 "America/Whitehorse",
614 "America/Dawson",
615 "America/Danmarkshavn",
616 "Asia/Jayapura",
617 "Australia/Sydney",
618 "Australia/Broken_Hill",
619 "Pacific/Auckland",
620 "Antarctica/McMurdo",
621 "America/St_Johns",
622 "Asia/Bangkok",
623 "Asia/Famagusta",
624 "Australia/Darwin",
625 "America/Los_Angeles",
626 "America/Vancouver",
627 "Antarctica/Palmer",
628 "Pacific/Port_Moresby",
629 "America/Belem",
630 "America/Santarem",
631 "Asia/Singapore",
632 "America/Recife",
633 "Pacific/Kanton",
634 "Pacific/Guadalcanal",
635 "Pacific/Pohnpei",
636 "Europe/Lisbon",
637 "Asia/Qostanay",
638 "Australia/Brisbane",
639 "Australia/Lindeman",
640 "America/Cancun",
641 "Asia/Qyzylorda",
642 "America/Punta_Arenas",
643 "America/Porto_Velho",
644 "America/Boa_Vista",
645 "Antarctica/Rothera",
646 "Asia/Kuching",
647 "America/Argentina/Salta",
648 "America/Argentina/San_Juan",
649 "America/Argentina/San_Luis",
650 "America/Argentina/Rio_Gallegos",
651 "America/Scoresbysund",
652 "Pacific/Tahiti",
653 "America/Hermosillo",
654 "Australia/Adelaide",
655 "Asia/Ho_Chi_Minh",
656 "Europe/Madrid",
657 "Antarctica/Syowa",
658 "Asia/Riyadh",
659 "Australia/Hobart",
660 "America/Thule",
661 "America/Argentina/Ushuaia",
662 "America/Araguaina",
663 "Antarctica/Troll",
664 "America/Argentina/Tucuman",
665 "Asia/Tashkent",
666 "Asia/Samarkand",
667 "Australia/Melbourne",
668 "Antarctica/Vostok",
669 "Pacific/Wake",
670 "Africa/Lagos",
671 "Asia/Hebron",
672 "Asia/Oral",
673 "Australia/Eucla",
674 "Australia/Perth",
675 "Asia/Urumqi",
676 ];
677
678 #[test]
679 fn test_tzname_buffer_fits_all_iana_names() {
680 let buf = tzname_buf();
681 let max_len = buf.len();
682
683 let mut failed_tz_names = vec![];
684
685 for &tz in KNOWN_TIMEZONE_NAMES {
686 if tz.len() >= max_len {
688 failed_tz_names.push(tz);
689 }
690 }
691
692 assert!(
693 failed_tz_names.is_empty(),
694 "One or more timezone names exceed the buffer length of {}. Max length of found timezone: {}\n{:?}",
695 max_len,
696 failed_tz_names.iter().map(|s| s.len()).max().unwrap(),
697 failed_tz_names
698 );
699 }
700
701 #[test]
702 fn test_tzname_buffer_correct_size() {
703 assert_eq!(
704 MAX_LEN, 64,
705 "Buffer length changed unexpectedly, ensure consistency with documented limit."
706 );
707 assert_eq!(
708 tzname_buf().len(),
709 MAX_LEN,
710 "Buffer length changed unexpectedly, ensure consistency with documented limit."
711 );
712 assert_eq!(
713 size_of_val(&tzname_buf()),
714 MAX_LEN,
715 "Buffer length changed unexpectedly, ensure consistency with documented limit."
716 );
717 }
718}