#
iana_time_zone/
ffi_utils.rs

    1//! Cross platform FFI helpers.
    2
    3#[cfg(any(test, target_os = "android"))]
    4use 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"))]
    8pub(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"))]
    32const 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"))]
    37pub(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)]
    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    /// 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}