1 | //! Cross platform FFI helpers. |
2 | |
3 | #[cfg (any(test, target_os = "android" ))] |
4 | use std::ffi::CStr; |
5 | |
6 | /// A buffer to store the timezone name when calling the C API. |
7 | #[cfg (any(test, target_vendor = "apple" , target_env = "ohos" ))] |
8 | pub(crate) mod buffer { |
9 | /// The longest name in the IANA time zone database is 32 ASCII characters long. |
10 | pub const MAX_LEN: usize = 64; |
11 | |
12 | /// Return a buffer to store the timezone name. |
13 | /// |
14 | /// The buffer is used to store the timezone name when calling the C API. |
15 | pub const fn tzname_buf() -> [u8; MAX_LEN] { |
16 | [0; MAX_LEN] |
17 | } |
18 | } |
19 | |
20 | // The system property named 'persist.sys.timezone' contains the name of the |
21 | // current timezone. |
22 | // |
23 | // From https://android.googlesource.com/platform/bionic/+/gingerbread-release/libc/docs/OVERVIEW.TXT#79: |
24 | // |
25 | // > The name of the current timezone is taken from the TZ environment variable, |
26 | // > if defined. Otherwise, the system property named 'persist.sys.timezone' is |
27 | // > checked instead. |
28 | // |
29 | // TODO: Use a `c"..."` literal when MSRV is upgraded beyond 1.77.0. |
30 | // https://doc.rust-lang.org/edition-guide/rust-2021/c-string-literals.html |
31 | #[cfg (any(test, target_os = "android" ))] |
32 | const ANDROID_TIMEZONE_PROPERTY_NAME: &[u8] = b"persist.sys.timezone \0" ; |
33 | |
34 | /// Return a [`CStr`] to access the timezone from an Android system properties |
35 | /// environment. |
36 | #[cfg (any(test, target_os = "android" ))] |
37 | pub(crate) fn android_timezone_property_name() -> &'static CStr { |
38 | // In tests or debug mode, opt into extra runtime checks. |
39 | if cfg!(any(test, debug_assertions)) { |
40 | return CStr::from_bytes_with_nul(ANDROID_TIMEZONE_PROPERTY_NAME).unwrap(); |
41 | } |
42 | |
43 | // SAFETY: the key is NUL-terminated and there are no other NULs, this |
44 | // invariant is checked in tests. |
45 | unsafe { CStr::from_bytes_with_nul_unchecked(ANDROID_TIMEZONE_PROPERTY_NAME) } |
46 | } |
47 | |
48 | #[cfg (test)] |
49 | mod 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 | /// An exhaustive set of IANA timezone names for testing. |
73 | /// |
74 | /// Pulled from Wikipedia as of Sat March 22, 2025: |
75 | /// |
76 | /// - <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones> |
77 | /// - <https://en.wikipedia.org/w/index.php?title=List_of_tz_database_time_zones&oldid=1281103182> |
78 | 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 | // Require max_len + 1 to account for an optional NUL terminator. |
687 | 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 | } |
719 | |