Skip to content

Commit

Permalink
[WIP] Add DateTimeFormat
Browse files Browse the repository at this point in the history
  • Loading branch information
zbraniecki committed Aug 21, 2020
1 parent f2d1713 commit 92405c8
Show file tree
Hide file tree
Showing 13 changed files with 833 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ members = [
"components/locale",
"components/num-util",
"components/pluralrules",
"components/datetime",
]
24 changes: 24 additions & 0 deletions components/datetime/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "icu-datetime"
description = "API for managing Unicode Language and Locale Identifiers"
version = "0.0.1"
authors = ["The ICU4X Project Developers"]
edition = "2018"
readme = "README.md"
repository = "https://github.com/unicode-org/icu4x"
license-file = "../../LICENSE"
categories = ["internationalization"]
include = [
"src/**/*",
"Cargo.toml",
"README.md"
]

[dependencies]

[dev-dependencies]
criterion = "0.3"

[[bench]]
name = "datetime"
harness = false
196 changes: 196 additions & 0 deletions components/datetime/benches/datetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
use criterion::{criterion_group, criterion_main, Criterion};
use std::fmt::Write;

use icu_datetime::date::DateTime;
use icu_datetime::options::{self, DateTimeFormatOptions};
use icu_datetime::provider::DummyDataProvider;
use icu_datetime::DateTimeFormat;

fn datetime_benches(c: &mut Criterion) {
let datetimes = vec![
DateTime::new(2001, 9, 8, 18, 46, 40),
DateTime::new(2017, 7, 13, 19, 40, 0),
DateTime::new(2020, 9, 13, 5, 26, 40),
DateTime::new(2021, 1, 6, 22, 13, 20),
DateTime::new(2021, 5, 2, 17, 0, 0),
DateTime::new(2021, 8, 26, 10, 46, 40),
DateTime::new(2021, 12, 20, 3, 33, 20),
DateTime::new(2022, 4, 14, 22, 20, 0),
DateTime::new(2022, 8, 8, 16, 6, 40),
DateTime::new(2033, 5, 17, 20, 33, 20),
];
let values = &[
("pl", options::style::Date::Full, options::style::Time::None),
("pl", options::style::Date::Long, options::style::Time::None),
(
"pl",
options::style::Date::Medium,
options::style::Time::None,
),
(
"pl",
options::style::Date::Short,
options::style::Time::None,
),
("pl", options::style::Date::None, options::style::Time::Full),
("pl", options::style::Date::None, options::style::Time::Long),
(
"pl",
options::style::Date::None,
options::style::Time::Medium,
),
(
"pl",
options::style::Date::None,
options::style::Time::Short,
),
("pl", options::style::Date::Full, options::style::Time::Full),
("pl", options::style::Date::Long, options::style::Time::Long),
(
"pl",
options::style::Date::Medium,
options::style::Time::Medium,
),
(
"pl",
options::style::Date::Short,
options::style::Time::Short,
),
];
let components = vec![
options::components::Bag {
year: options::components::Numeric::TwoDigit,
month: options::components::Month::Long,
day: options::components::Numeric::TwoDigit,
..Default::default()
},
options::components::Bag {
hour: options::components::Numeric::TwoDigit,
minute: options::components::Numeric::Numeric,
second: options::components::Numeric::Numeric,
hour_cycle: options::components::HourCycle::H23,
..Default::default()
},
options::components::Bag {
year: options::components::Numeric::Numeric,
month: options::components::Month::Short,
day: options::components::Numeric::Numeric,
weekday: options::components::Text::Long,
era: options::components::Text::Long,
hour: options::components::Numeric::Numeric,
minute: options::components::Numeric::TwoDigit,
second: options::components::Numeric::TwoDigit,
hour_cycle: options::components::HourCycle::H12,
time_zone_name: options::components::TimeZoneName::Long,
..Default::default()
},
options::components::Bag {
hour: options::components::Numeric::Numeric,
minute: options::components::Numeric::TwoDigit,
..Default::default()
},
options::components::Bag {
minute: options::components::Numeric::TwoDigit,
second: options::components::Numeric::TwoDigit,
..Default::default()
},
];

let mut results = vec![];

for _ in 0..datetimes.len() {
results.push(String::new());
}

let dp = DummyDataProvider::default();

{
let mut group = c.benchmark_group("datetime");

group.bench_function("DateTimeFormat/format_to_write", |b| {
b.iter(|| {
for value in values {
let options = DateTimeFormatOptions::Style(options::style::Bag {
date: value.1,
time: value.2,
..Default::default()
});
let dtf = DateTimeFormat::try_new(&dp, &options);

for (dt, result) in datetimes.iter().zip(results.iter_mut()) {
result.clear();
let _ = dtf.format_to_write(&dt, result);
}
}
})
});

group.bench_function("DateTimeFormat/format_to_string", |b| {
b.iter(|| {
for value in values {
let options = DateTimeFormatOptions::Style(options::style::Bag {
date: value.1,
time: value.2,
..Default::default()
});
let dtf = DateTimeFormat::try_new(&dp, &options);

for dt in &datetimes {
let _ = dtf.format_to_string(&dt);
}
}
})
});

group.bench_function("FormattedDateTime/format", |b| {
b.iter(|| {
for value in values {
let options = DateTimeFormatOptions::Style(options::style::Bag {
date: value.1,
time: value.2,
..Default::default()
});
let dtf = DateTimeFormat::try_new(&dp, &options);

for (dt, result) in datetimes.iter().zip(results.iter_mut()) {
result.clear();
let fdt = dtf.format(&dt);
write!(result, "{}", fdt).unwrap();
}
}
})
});

group.bench_function("FormattedDateTime/to_string", |b| {
b.iter(|| {
for value in values {
let options = DateTimeFormatOptions::Style(options::style::Bag {
date: value.1,
time: value.2,
..Default::default()
});
let dtf = DateTimeFormat::try_new(&dp, &options);

for dt in &datetimes {
let fdt = dtf.format(&dt);
let _ = fdt.to_string();
}
}
})
});

group.bench_function("options/write_skeleton", |b| {
b.iter(|| {
for component in &components {
let mut s = String::new();
component.write_skeleton(&mut s).unwrap();
}
})
});

group.finish();
}
}

criterion_group!(benches, datetime_benches,);
criterion_main!(benches);
29 changes: 29 additions & 0 deletions components/datetime/src/date.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#[derive(Default)]
pub struct DateTime {
pub year: usize,
pub month: usize,
pub day: usize,
pub hour: usize,
pub minute: usize,
pub second: usize,
}

impl DateTime {
pub fn new(
year: usize,
month: usize,
day: usize,
hour: usize,
minute: usize,
second: usize,
) -> Self {
Self {
year,
month,
day,
hour,
minute,
second,
}
}
}
141 changes: 141 additions & 0 deletions components/datetime/src/fields.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use std::fmt;

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FieldLength {
Short = 1,
TwoDigit = 2,
Abbreviated = 3,
Wide = 4,
Narrow = 5,
}

#[derive(Debug, PartialEq)]
pub enum FieldSymbol {
Era,
Year(Year),
Month(Month),
Day(Day),
Hour(Hour),
}

impl FieldSymbol {
pub fn write(&self, w: &mut impl fmt::Write) -> fmt::Result {
match self {
Self::Era => w.write_char('G'),
Self::Year(year) => year.write(w),
Self::Month(month) => month.write(w),
Self::Day(day) => day.write(w),
Self::Hour(hour) => hour.write(w),
}
}
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FieldType {
Era,
Year,
Month,
Day,
Hour,
}

impl FieldType {
pub fn iter() -> impl Iterator<Item = &'static Self> {
[Self::Era, Self::Year, Self::Month, Self::Day].iter()
}
}

#[derive(Debug, PartialEq)]
pub enum Year {
Calendar,
WeekOf,
Extended,
Cyclic,
RelatedGregorian,
}

impl Year {
pub fn write(&self, w: &mut impl fmt::Write) -> fmt::Result {
w.write_char(match self {
Self::Calendar => 'y',
Self::WeekOf => 'Y',
Self::Extended => 'u',
Self::Cyclic => 'U',
Self::RelatedGregorian => 'r',
})
}
}

#[derive(Debug, PartialEq)]
pub enum Month {
Format,
StandAlone,
}

impl Month {
pub fn write(&self, w: &mut impl fmt::Write) -> fmt::Result {
w.write_char(match self {
Self::Format => 'M',
Self::StandAlone => 'L',
})
}
}

#[derive(Debug, PartialEq)]
pub enum Day {
DayOfMonth,
DayOfYear,
DayOfWeekInMonth,
ModifiedJulianDay,
}

impl Day {
pub fn write(&self, w: &mut impl fmt::Write) -> fmt::Result {
w.write_char(match self {
Self::DayOfMonth => 'd',
Self::DayOfYear => 'D',
Self::DayOfWeekInMonth => 'F',
Self::ModifiedJulianDay => 'g',
})
}
}

#[derive(Debug, PartialEq)]
pub enum Hour {
H11,
H12,
H23,
H24,
Preferred,
PreferredNoDayPeriod,
PreferredFlexibleDayPeriod,
}

impl Hour {
pub fn write(&self, w: &mut impl fmt::Write) -> fmt::Result {
w.write_char(match self {
Self::H11 => 'K',
Self::H12 => 'h',
Self::H23 => 'H',
Self::H24 => 'k',
Self::Preferred => 'j',
Self::PreferredNoDayPeriod => 'J',
Self::PreferredFlexibleDayPeriod => 'C',
})
}
}

#[derive(Debug, PartialEq)]
pub struct Field {
pub symbol: FieldSymbol,
pub length: FieldLength,
}

impl Field {
pub fn write_pattern(&self, w: &mut impl fmt::Write) -> fmt::Result {
for _ in 0..(self.length as u8) {
self.symbol.write(w)?;
}
Ok(())
}
}
Loading

0 comments on commit 92405c8

Please sign in to comment.