Skip to content

Commit cab350e

Browse files
committed
date-picker-data
1 parent 592cfbe commit cab350e

File tree

1 file changed

+36
-50
lines changed

1 file changed

+36
-50
lines changed

tutorials/date-picker-data.md

Lines changed: 36 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ This will generate a `ccp.blob` file containing data for Chakma.
4141
To use blob data, we will need to add the `icu_provider_blob` crate to our project:
4242

4343
```console
44-
cargo add icu_provider_blob
44+
cargo add icu_provider_blob --features alloc
4545
```
4646

4747
We also need to enable the `serde` feature on the `icu` crate to enable deserialization support:
@@ -58,29 +58,23 @@ locale is Chakma:
5858
use icu::locale::locale;
5959
use icu_provider_blob::BlobDataProvider;
6060

61-
// Just below the imports (fill in the path):
62-
const CCP_BLOB_PATH: &str = "<absolute path to ccp.blob>";
63-
64-
let datetime_formatter = if locale == locale!("ccp") {
61+
// replace the date_formatter creation
62+
let date_formatter = if locale == locale!("ccp") {
6563
println!("Using buffer provider");
6664

67-
let blob = std::fs::read(CCP_BLOB_PATH)
65+
let blob = std::fs::read("ccp.blob")
6866
.expect("blob should read successfully")
6967
.into();
7068

7169
let provider =
7270
BlobDataProvider::try_new_from_blob(blob).expect("deserialization should succeed");
7371

74-
DateTimeFormatter::try_new_with_buffer_provider(
75-
&provider,
76-
&(&locale).into(),
77-
Default::default(),
78-
)
79-
.expect("should have data for selected locale")
72+
DateTimeFormatter::try_new_with_buffer_provider(&provider, locale.into(), YMD::medium())
73+
.expect("should have data for selected locale")
8074
} else {
8175
// As before
82-
DateTimeFormatter::try_new(&(&locale).into(), Default::default())
83-
.expect("should have data for selected locale")
76+
DateTimeFormatter::try_new(locale.into(), YMD::medium())
77+
.expect("should have data for specified locale")
8478
};
8579
```
8680

@@ -106,22 +100,19 @@ function load_blob(url, callback) {
106100

107101
if (localeStr == "ccp") {
108102
load_blob("https://storage.googleapis.com/static-493776/icu4x_2023-11-03/ccp.blob", (blob) => {
109-
let dateTimeFormatter = ICU4XDateTimeFormatter.create_with_lengths(
110-
ICU4XDataProvider.create_from_byte_slice(blob),
103+
let dateTimeFormatter = DateTimeFormatter.createYmdtWithProvider(
104+
DataProvider.createFromBlob(blob),
111105
locale,
112-
ICU4XDateLength.Medium,
113-
ICU4XTimeLength.Medium,
106+
DateTimeLength.Long,
114107
);
115-
document.getElementById("output").innerText = dateFormatter.format_iso_datetime(isoDateTime);
108+
document.getElementById("output").innerText = dateTimeFormatter.formatIso(isoDate, time);
116109
})
117110
} else {
118-
let dateTimeFormatter = ICU4XDateTimeFormatter.create_with_lengths(
119-
ICU4XDataProvider.create_compiled(),
120-
locale,
121-
ICU4XDateLength.Medium,
122-
ICU4XTimeLength.Medium,
111+
let dateTimeFormatter = DateTimeFormatter.createYmdt(
112+
locale,
113+
DateTimeLength.Long,
123114
);
124-
document.getElementById("output").innerText = dateFormatter.format_iso_datetime(isoDateTime);
115+
document.getElementById("output").innerText = dateTimeFormatter.formatIso(isoDate, time);
125116
}
126117
```
127118

@@ -134,43 +125,36 @@ Note: the following steps are currently only possible in Rust. 🤷
134125
When we ran `icu4x-datagen`, we passed `--markers all`, which make it generate *all* data for the Chakma locale, even though we only need date formatting. We can make `icu4x-datagen` analyze our binary to figure out which markers are needed:
135126

136127
```console
137-
icu4x-datagen --markers-for-bin target/debug/tutorial --locales ccp --format blob --out ccp_smaller.blob
128+
cargo build --release
129+
icu4x-datagen --markers-for-bin target/release/tutorial --locales ccp --format blob --out ccp_smaller.blob
138130
```
139131

140-
Note: you usually want to build with the `--release` flag, and analyze that binary, but we don't have all day.
132+
Note: you usually want to build with the `--release` flag, and analyze that binary.
141133

142134
This should generate a lot fewer markers!
143135

144136
Let's look at the sizes:
145137

146138
```console
147139
wc -c *.blob
148-
# 656767 ccp.blob
149-
# 45471 ccp_smaller.blob
140+
# 5448603 ccp.blob
141+
# 13711 ccp_smaller.blob
150142
```
151143

152144
This is much better! Rerun your app with `ccp_smaller.blob` to make sure it still works!
153145

154146
## 5. Slimming the data pack ... again
155147

156-
The last datagen invocation still produced a lot of markers, as you saw in its output. This is because we used the `DateFormatter` API, which can format dates for a lot of different calendars. However, if we are only using it with an Gregorian calendar date, so we don't need Coptic, Indian, etc. date formatting data.
148+
The last datagen invocation still produced a lot of markers, as you saw in its output. This is because we used the `DateTimeFormatter` API, which can format dates for a lot of different calendars (remember `en-u-ca-hebrew`). However, if we were only using it with a Gregorian calendar date, we wouldn't need Coptic, Indian, etc. date formatting data. Now, how do we communicate this to `--markers-for-bin`? Turns out, `icu::datetime` also exposes a `FixedCalendarDateTimeFormatter`, which is generic in a single calendar type. If you use this API instead, `--markers-for-bin` will only include the markers for that one calendar type.
157149

158-
We've seen that `DateFormatter` pulls in a lot of data. It would be nice if we could tell it that we'll only ever use it with Gregorian dates. Turns out we can! `icu::datetime` also exposes a `TypedDateFormatter<C>`, which is generic in a single calendar type. If you use this API instead (instantiated as `TypedDateFormatter<Gregorian>`), `--markers-for-bin` will give you exactly the markers we manually selected in the last section. However, now you can be sure that you didn't make a mistake selecting the markers (which would be an awkward runtime error), and that you will never accidentally pass a non-Gregorian date into the formatter (which would an awkward runtime error with `DateFormatter`, but is a compile-time error with `TypeDateFormatter`).
150+
Replace the `DateTimeFormatter::try_new` calls with `FixedCalendarDateTimeFormatter::try_new`, and change the `format` invocation to convert the input to the Gregorian calendar:
159151

160152
```rust
161-
let date_formatter = TypedDateFormatter::<Gregorian>::try_new_with_length(
162-
&(&locale).into(),
163-
length::Date::Medium,
164-
)
165-
.expect("should have data for selected locale");
166-
167-
println!(
168-
"Date: {}",
169-
// We need to convert to the explicit calendar via `.to_calendar()`.
170-
date_formatter.format(&iso_date.to_calendar(Gregorian)),
171-
);
153+
println!("Date: {}", date_formatter.format(&iso_date.to_calendar(Gregorian)));
172154
```
173155

156+
The generic type of `FixedCalendarDateTimeFormatter` will be inferred from the input, which now has type `&Date<Gregorian>` now. Unlike `DateTimeFormatter`, `FixedCalendarDateTimeFormatter` never applies calendar conversions on its input, so it will be a `FixedCalendarDateTimeFormatter<Gregorian, ...>`.
157+
174158
Now we can run datagen with `--markers-for-bin` again:
175159

176160
```console
@@ -181,20 +165,22 @@ icu4x-datagen --markers-for-bin target/release/tutorial --locales ccp --format b
181165
The output will be much shorter:
182166

183167
```console
184-
INFO [icu_provider_export::export_impl] Generating marker datetime/gregory/datelengths@1
185-
INFO [icu_provider_export::export_impl] Generating marker datetime/gregory/datesymbols@1
186-
INFO [icu_provider_export::export_impl] Generating marker datetime/week_data@1
187-
INFO [icu_provider_export::export_impl] Generating marker decimal/symbols@2
188-
INFO [icu_provider_export::export_impl] Generating marker plurals/ordinal@1
168+
2025-05-14T14:26:52.306Z INFO [icu_provider_export::export_impl] Generated marker DatetimeNamesMonthGregorianV1
169+
2025-05-14T14:26:52.308Z INFO [icu_provider_export::export_impl] Generated marker DatetimeNamesYearGregorianV1
170+
2025-05-14T14:26:52.312Z INFO [icu_provider_export::export_impl] Generated marker DatetimePatternsDateGregorianV1
171+
2025-05-14T14:26:52.324Z INFO [icu_provider_export::export_impl] Generated marker DecimalDigitsV1
172+
2025-05-14T14:26:52.325Z INFO [icu_provider_export::export_impl] Generated marker DecimalSymbolsV1
189173
```
190174

191175
And the blob will also be much smaller at the sizes:
192176

193177
```console
194178
wc -c *.blob
195-
# 656767 ccp.blob
196-
# 45471 ccp_smaller.blob
197-
# 4639 ccp_smallest.blob
179+
# 5448603 ccp.blob
180+
# 13711 ccp_smaller.blob
181+
# 4711 ccp_smallest.blob
198182
```
199183

200184
Rerun your app with `ccp_smallest.blob` to make sure it still works!
185+
186+
Does the locale `en-u-ca-hebrew` still use the Hebrew calendar? Why is that?

0 commit comments

Comments
 (0)