Skip to content

Commit

Permalink
bye
Browse files Browse the repository at this point in the history
  • Loading branch information
robertbastian committed Feb 16, 2025
1 parent a6a14a8 commit 05d2224
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 516 deletions.
6 changes: 5 additions & 1 deletion provider/source/src/cldr_serde/time_zones/bcp47_tzid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! Sample file:
//! <https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-bcp47/bcp47/timezone.json>
use icu::time::TimeZone;
use icu::{locale::subtags::Region, time::TimeZone};
use serde::Deserialize;
use std::collections::BTreeMap;

Expand All @@ -25,6 +25,10 @@ pub(crate) struct Bcp47TzidAliasData {
pub(crate) since: Option<String>,
#[serde(rename = "_iana")]
pub(crate) iana: Option<String>,
#[serde(rename = "_noregion")]
pub(crate) noregion: Option<bool>,
#[serde(rename = "_region")]
pub(crate) region: Option<Region>,
}

#[derive(PartialEq, Debug, Deserialize)]
Expand Down
2 changes: 0 additions & 2 deletions provider/source/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ impl SourceDataProvider {
tzdb_paths: Some(Arc::new(TzdbCache {
root: AbstractFs::new(root)?,
transitions: Default::default(),
zone_tab: Default::default(),
})),
..self
})
Expand Down Expand Up @@ -267,7 +266,6 @@ impl SourceDataProvider {
"https://www.iana.org/time-zones/repository/releases/tzdata{tag}.tar.gz",
)),
transitions: Default::default(),
zone_tab: Default::default(),
})),
..self
}
Expand Down
47 changes: 0 additions & 47 deletions provider/source/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use elsa::sync::FrozenMap;
use icu_locale_core::subtags::Region;
use icu_provider::prelude::*;
use std::any::Any;
use std::collections::BTreeMap;
Expand Down Expand Up @@ -387,55 +386,9 @@ impl AbstractFs {
pub(crate) struct TzdbCache {
pub(crate) root: AbstractFs,
pub(crate) transitions: OnceLock<Result<parse_zoneinfo::table::Table, DataError>>,
pub(crate) zone_tab: OnceLock<Result<BTreeMap<String, Region>, DataError>>,
}

fn strip_comments(mut line: String) -> String {
if let Some(pos) = line.find('#') {
line.truncate(pos);
};
line
}

impl TzdbCache {
pub(crate) fn zone_tab(&self) -> Result<&BTreeMap<String, Region>, DataError> {
self.zone_tab
.get_or_init(|| {
let mut r = BTreeMap::new();

for line in self
.root
.read_to_string("zone.tab")?
.lines()
.map(ToOwned::to_owned)
.map(strip_comments)
{
let mut fields = line.split('\t');

let Some(country_code) = fields.next() else {
continue;
};

let Ok(region) = country_code.parse() else {
continue;
};

let Some(_coords) = fields.next() else {
continue;
};

let Some(iana) = fields.next() else {
continue;
};

r.insert(iana.to_owned(), region);
}
Ok(r)
})
.as_ref()
.map_err(|&e| e)
}

pub(crate) fn transitions(&self) -> Result<&parse_zoneinfo::table::Table, DataError> {
use parse_zoneinfo::line::{Line, LineParser};
use parse_zoneinfo::table::TableBuilder;
Expand Down
5 changes: 2 additions & 3 deletions provider/source/src/tests/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,10 +688,9 @@ impl SourceDataProvider {
("etcetera", include_bytes!("../../tests/data/tzdb/etcetera").as_slice()),
("europe", include_bytes!("../../tests/data/tzdb/europe").as_slice()),
("northamerica", include_bytes!("../../tests/data/tzdb/northamerica").as_slice()),
("southamerica", include_bytes!("../../tests/data/tzdb/southamerica").as_slice()),
("zone.tab", include_bytes!("../../tests/data/tzdb/zone.tab").as_slice())
("southamerica", include_bytes!("../../tests/data/tzdb/southamerica").as_slice())
].into_iter().collect(),
), transitions: Default::default(), zone_tab: Default::default() })),
), transitions: Default::default() })),
..SourceDataProvider::new_custom()
})
.clone()
Expand Down
73 changes: 59 additions & 14 deletions provider/source/src/time_zones/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use crate::SourceDataProvider;
use core::hash::Hash;
use core::hash::Hasher;
use icu::datetime::provider::time_zones::*;
use icu::locale::subtags::region;
use icu::time::provider::*;
use icu_locale_core::subtags::Region;
use icu_provider::prelude::*;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::HashSet;
use std::sync::OnceLock;
use twox_hash::XxHash64;
Expand Down Expand Up @@ -201,28 +203,71 @@ impl SourceDataProvider {
.map(|(&region, iana)| (iana, region))
.collect::<BTreeMap<_, _>>();

let bcp47_tzids = self.bcp47_to_canonical_iana_map()?;
let bcp47_tzids_resource = &self
.cldr()?
.bcp47()
.read_and_parse::<cldr_serde::time_zones::bcp47_tzid::Resource>(
"timezone.json",
)?
.keyword
.u
.time_zones
.values;

let zone_tab = self.tzdb()?.zone_tab()?;
let mut zones_per_region: BTreeMap<icu::locale::subtags::Region, usize> =
BTreeMap::new();
let mut regions_to_zones: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();

for &region in bcp47_tzids.values().flat_map(|iana| zone_tab.get(iana)) {
*zones_per_region.entry(region).or_default() += 1;
for (&bcp47_tzid, bcp47_tzid_data) in bcp47_tzids_resource {
let region = if bcp47_tzid_data.deprecated == Some(true)
|| bcp47_tzid_data.noregion == Some(true)
{
continue;
} else if let Some(region) = bcp47_tzid_data.region {
region
} else {
bcp47_tzid.0.resize::<2>().as_str().parse().unwrap()
};

// backfill
let region = match bcp47_tzid.0.as_bytes() {
b"unk"
| b"gmt"
| b"cst6cdt"
| b"est5edt"
| b"mst7mdt"
| b"pst8pdt"
| &[b'u', b't', b'c', ..] => continue,
b"ancur" => region!("CW"),
b"fimhq" => region!("AX"),
b"gpmsb" => region!("MF"),
b"gpsbh" => region!("BL"),
b"gazastrp" | b"hebron" => region!("PS"),
b"jeruslm" => region!("IL"),
_ => region,
};

regions_to_zones
.entry(region)
.or_default()
.insert(bcp47_tzid);
}

Ok(bcp47_tzids
let single_zone_regions = regions_to_zones
.iter()
.filter_map(|(region, zones)| {
(zones.len() == 1).then_some((zones.first().unwrap(), region))
})
.collect::<BTreeMap<_, _>>();

Ok(self
.bcp47_to_canonical_iana_map()?
.iter()
.filter_map(|(bcp47, canonical_iana)| {
Some((
*bcp47,
primary_zones.get(canonical_iana).copied().or_else(|| {
let region = *zone_tab.get(canonical_iana)?;
if zones_per_region.get(&region).copied().unwrap_or_default() > 1 {
return None;
}
Some(region)
})?,
primary_zones
.get(canonical_iana)
.copied()
.or_else(|| single_zone_regions.get(bcp47).copied().copied())?,
))
})
.collect())
Expand Down
Loading

0 comments on commit 05d2224

Please sign in to comment.