Skip to content

Instantly share code, notes, and snippets.

@zbraniecki
Last active November 11, 2025 21:22
Show Gist options
  • Select an option

  • Save zbraniecki/99b6c1f24e356dc7d91ab948c1b8dcb8 to your computer and use it in GitHub Desktop.

Select an option

Save zbraniecki/99b6c1f24e356dc7d91ab948c1b8dcb8 to your computer and use it in GitHub Desktop.
ICU4X 2.1 Interactive Intro

Interactive Date Picker (JS)

In this tutorial, you will learn how to build an end-to-end application using ICU4X to format a date and time with some default locales and additional locales loaded dynamically.

1. Installing ICU4X

Installing dependencies is always your first step.

We recommend using CodePen to follow along. To load ICU4X into CodePen, you can use this snippet in the JavaScript editor:

import { Locale, DateFormatter, IsoDate, DateTimeLength } from "https://unpkg.com/[email protected]";

This loads the full ICU4X WebAssembly file. Since it may take a few seconds to load on slow connections, we'll create a loading div. Add this to your HTML:

<div id="loading">Loading…</div>

<div id="inputoutput" style="display: none">
  <p>Ready to rumble!</p>
</div>

And in JavaScript, add these lines after the import statement:

document.getElementById("loading").style.display = "none";
document.getElementById("inputoutput").style.display = "block";

2. Parsing an Input Locale

Here, we will accept a locale string from the user and parse it into an ICU4X Locale.

In the HTML, create an input element for accepting a locale string input, and an output element to echo it back to the user. Add this inside of the inputoutput div:

<!-- inside of div id="inputoutput" -->
<p><label>Locale: <input type="text" id="localeinput" value="en-US"/></label></p>
<p>Output: <output id="output"></output></p>

And in JavaScript:

// Create a function that updates the UI:
function update() {
    try {
        let localeStr = document.getElementById("localeinput").value;

        let locale = Locale.fromString(localeStr);
        let output = locale.toString();

        document.getElementById("output").innerText = output;
    } catch(e) {
        document.getElementById("output").innerText = e;
    }
}

// Run the function whenever the locale input changes:
document.getElementById("localeinput").addEventListener("keyup", update, false);

// Also run the function right now to initialize the UI:
update();

Try inputting locales in non-canonical syntax and see them normalized!

Locale: ES-419 Output: es-419

3. Formatting a Date

Now we will use built-in locale data to produce a formatted date.

In JavaScript, we will create a datetime input field.

Add this to the HTML:

<!-- inside of div id="inputoutput" -->
<p><label>Date: <input type="date" id="dateinput"/></label></p>

And this to JavaScript:

// Run the function whenever the date input changes:
document.getElementById("dateinput").addEventListener("input", update, false);

// Put the following in the update() function, inside the try block:
let dateStr = document.getElementById("dateinput").value;

let dateObj = dateStr ? new Date(dateStr) : new Date();
let isoDate = new IsoDate(dateObj.getFullYear(), dateObj.getMonth() + 1, dateObj.getDate());
let dateFormatter = DateFormatter.createYmd(locale, DateTimeLength.Long);
let output = dateFormatter.formatIso(isoDate);

document.getElementById("output").innerText = output;

Try this in several locales, like en (English), en-GB (British English), and th (Thai). Observe how differently dates are represented in locales around the world! You can explicitly specify arbitrary calendar systems using the u-ca Unicode extension keyword in the locale. Try en-u-ca-hebrew!

4. Formatting date and time

Now we would also like to format the current time.

Use the API documentation for Time and DateTimeFormatter to expand your app to format both a date and a time.

Hint: You can create an HTML time picker with

<p><label>Time: <input type="time" id="timeinput" value="10:10"/></label></p>

Hint: You can create a Date from dateStr and timeStr with

let dateObj = dateStr && timeStr ? new Date(dateStr + " " + timeStr) : new Date();

Note that Dates constructed this way will be in UTC.

Interactive Date Picker (Rust)

In this tutorial, you will learn how to build an end-to-end application using ICU4X to format a date and time with some default locales and additional locales loaded dynamically.

1. Installing ICU4X

Installing dependencies is always your first step.

Part 1

Verify that Rust is installed. If it's not, you can install it in a few seconds from https://rustup.rs/.

cargo --version
# cargo 1.91.1 (ea2d97820 2025-10-10)

Create a new Rust binary crate with icu4x as a dependency:

cargo new --bin tutorial
cd tutorial
cargo add icu

2. Parsing an Input Locale

Here, we will accept a locale string from the user and parse it into an ICU4X Locale.

First, we will use Rust APIs to accept a string from user input on the command line. Then we can parse the input string as an ICU4X Locale. Add the following to your fn main():

// At the top of the file:
use icu::locale::Locale;

// In the main() function:
print!("Enter your locale: ");
std::io::Write::flush(&mut std::io::stdout()).unwrap();
let locale_str = {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf
};

// Since the string contains whitespace, we must call `.trim()`:
let locale = match locale_str.trim().parse::<Locale>() {
    Ok(locale) => {
        println!("You entered: {locale}");
        locale
    }
    Err(e) => {
        panic!("Error parsing locale! {e}");
    }
};

Try inputting locales in non-canonical syntax and see them normalized!

cargo run
Enter your locale: DE-CH
You entered: de-CH

3. Formatting a Date

Now we will use built-in locale data to produce a formatted date.

We would like to format today's date. We will get this from the time crate, which you need to add:

cargo add time --features local-offset

Now we can write the Rust code:

// At the top of the file:
use icu::datetime::{DateTimeFormatter, fieldsets::YMD, input::Date};
use icu::locale::locale;

let locale = locale!("en-GB");

// Put the following in the main() function:
let iso_date = {
    let current_offset_date_time = time::OffsetDateTime::now_local().unwrap();
    Date::try_new_iso(
        current_offset_date_time.year(),
        current_offset_date_time.month() as u8,
        current_offset_date_time.day(),
    )
    .unwrap()
};

// Create and use an ICU4X date formatter:
let date_formatter = DateTimeFormatter::try_new(
    locale.into(),
    YMD::medium(),
)
.expect("should have data for specified locale");
println!(
    "Date: {}",
    date_formatter.format(&iso_date)
);

Try this in several locales, like en (English), en-GB (British English), and th (Thai). Observe how differently dates are represented in locales around the world! You can explicitly specify arbitrary calendar systems using the u-ca Unicode extension keyword in the locale. Try en-u-ca-hebrew!

4. Formatting date and time

Now we would also like to format the current time.

Use the API documentation for icu::time::DateTime and icu::datetime::fieldsets to expand your app to format both date and time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment