| 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 | |