oxedyne/fe2o3/fe2o3_datime/tests/advanced_formatter_demo.rs
8.6 KiB, 19 runs
created by r1870400018:8641, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! Comprehensive demonstration of advanced formatter capabilities. |
| 2 | //! |
| 3 | //! This test demonstrates the enhanced formatting features including: |
| 4 | //! - Locale-specific formatting |
| 5 | //! - Custom month and day names |
| 6 | //! - Ordinal suffixes (1st, 2nd, 3rd) |
| 7 | //! - Week of year and era formatting |
| 8 | //! - AM/PM customization |
| 9 | //! |
| 10 | //! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\ |
| 11 | //! Anthropic Claude |
| 12 | |
| 13 | use oxedyne_fe2o3_core::prelude::*; |
| 14 | use oxedyne_fe2o3_datime::{ |
| 15 | format::{CalClockFormatter, FormatPattern, Locale}, |
| 16 | calendar::CalendarDate, |
| 17 | clock::ClockTime, |
| 18 | constant::{MonthOfYear, DayOfWeek}, |
| 19 | time::{CalClock, CalClockZone}, |
| 20 | }; |
| 21 | |
| 22 | use std::collections::HashMap; |
| 23 | |
| 24 | #[test] |
| 25 | fn test_advanced_formatter_features() -> Outcome<()> { |
| 26 | println!("=== Advanced Formatter Features Demo ==="); |
| 27 | |
| 28 | let zone = CalClockZone::utc(); |
| 29 | let calclock = res!(CalClock::now(zone.clone())); |
| 30 | |
| 31 | // Test 1: Basic formatting with various patterns |
| 32 | println!("\n📅 Test 1: Basic Pattern Formatting"); |
| 33 | |
| 34 | let formatter = CalClockFormatter::new(); |
| 35 | let patterns = vec![ |
| 36 | ("yyyy-MM-dd", "ISO date"), |
| 37 | ("dd/MM/yyyy", "European date"), |
| 38 | ("MM/dd/yyyy", "US date"), |
| 39 | ("EEEE, MMMM d, yyyy", "Full date"), |
| 40 | ("EEE, MMM d, ''yy", "Short date"), |
| 41 | ("h:mm:ss a", "12-hour time"), |
| 42 | ("HH:mm:ss", "24-hour time"), |
| 43 | ("yyyy-MM-dd'T'HH:mm:ss", "ISO datetime"), |
| 44 | ("yyyy-MM-dd HH:mm:ss Z", "With timezone offset"), |
| 45 | ("EEEE, MMMM d, yyyy 'at' h:mm a", "Natural format"), |
| 46 | ]; |
| 47 | |
| 48 | for (pattern_str, description) in patterns { |
| 49 | let pattern = res!(FormatPattern::new(pattern_str)); |
| 50 | let formatted = res!(formatter.format_with_pattern(&calclock, &pattern)); |
| 51 | println!(" {} → {}: {}", pattern_str, description, formatted); |
| 52 | } |
| 53 | |
| 54 | // Test 2: Locale-specific formatting |
| 55 | println!("\n🌍 Test 2: Locale-Specific Formatting"); |
| 56 | |
| 57 | let locales = vec![ |
| 58 | ("en-US", Locale::us()), |
| 59 | ("en-GB", Locale::uk()), |
| 60 | ("de-DE", Locale::germany()), |
| 61 | ("fr-FR", Locale::france()), |
| 62 | ("ja-JP", Locale::japan()), |
| 63 | ("ISO", Locale::iso()), |
| 64 | ]; |
| 65 | |
| 66 | for (locale_id, locale) in locales { |
| 67 | let formatted = res!(formatter.format_with_locale(&calclock, &locale)); |
| 68 | println!(" {}: {}", locale_id, formatted); |
| 69 | } |
| 70 | |
| 71 | // Test 3: Custom localization |
| 72 | println!("\n🎨 Test 3: Custom Localization"); |
| 73 | |
| 74 | // Create formatter with Spanish month and day names |
| 75 | let mut spanish_months = HashMap::new(); |
| 76 | spanish_months.insert(MonthOfYear::January, ("ene".to_string(), "enero".to_string())); |
| 77 | spanish_months.insert(MonthOfYear::February, ("feb".to_string(), "febrero".to_string())); |
| 78 | spanish_months.insert(MonthOfYear::March, ("mar".to_string(), "marzo".to_string())); |
| 79 | spanish_months.insert(MonthOfYear::April, ("abr".to_string(), "abril".to_string())); |
| 80 | spanish_months.insert(MonthOfYear::May, ("may".to_string(), "mayo".to_string())); |
| 81 | spanish_months.insert(MonthOfYear::June, ("jun".to_string(), "junio".to_string())); |
| 82 | spanish_months.insert(MonthOfYear::July, ("jul".to_string(), "julio".to_string())); |
| 83 | spanish_months.insert(MonthOfYear::August, ("ago".to_string(), "agosto".to_string())); |
| 84 | spanish_months.insert(MonthOfYear::September, ("sep".to_string(), "septiembre".to_string())); |
| 85 | spanish_months.insert(MonthOfYear::October, ("oct".to_string(), "octubre".to_string())); |
| 86 | spanish_months.insert(MonthOfYear::November, ("nov".to_string(), "noviembre".to_string())); |
| 87 | spanish_months.insert(MonthOfYear::December, ("dic".to_string(), "diciembre".to_string())); |
| 88 | |
| 89 | let mut spanish_days = HashMap::new(); |
| 90 | spanish_days.insert(DayOfWeek::Monday, ("lun".to_string(), "lunes".to_string())); |
| 91 | spanish_days.insert(DayOfWeek::Tuesday, ("mar".to_string(), "martes".to_string())); |
| 92 | spanish_days.insert(DayOfWeek::Wednesday, ("mié".to_string(), "miércoles".to_string())); |
| 93 | spanish_days.insert(DayOfWeek::Thursday, ("jue".to_string(), "jueves".to_string())); |
| 94 | spanish_days.insert(DayOfWeek::Friday, ("vie".to_string(), "viernes".to_string())); |
| 95 | spanish_days.insert(DayOfWeek::Saturday, ("sáb".to_string(), "sábado".to_string())); |
| 96 | spanish_days.insert(DayOfWeek::Sunday, ("dom".to_string(), "domingo".to_string())); |
| 97 | |
| 98 | let spanish_formatter = CalClockFormatter::new() |
| 99 | .set_month_names(spanish_months) |
| 100 | .set_day_names(spanish_days) |
| 101 | .set_am_pm_markers("a.m.".to_string(), "p.m.".to_string()); |
| 102 | |
| 103 | let pattern = res!(FormatPattern::new("EEEE, d 'de' MMMM 'de' yyyy, h:mm a")); |
| 104 | let spanish_formatted = res!(spanish_formatter.format_with_pattern(&calclock, &pattern)); |
| 105 | println!(" Spanish: {}", spanish_formatted); |
| 106 | |
| 107 | // Test 4: Ordinal suffixes |
| 108 | println!("\n🔢 Test 4: Ordinal Suffixes"); |
| 109 | |
| 110 | let ordinal_formatter = CalClockFormatter::new().enable_ordinals(); |
| 111 | |
| 112 | // Test various dates to show ordinal suffixes |
| 113 | let test_dates = vec![ |
| 114 | (2024, MonthOfYear::January, 1), |
| 115 | (2024, MonthOfYear::January, 2), |
| 116 | (2024, MonthOfYear::January, 3), |
| 117 | (2024, MonthOfYear::January, 21), |
| 118 | (2024, MonthOfYear::January, 22), |
| 119 | (2024, MonthOfYear::January, 23), |
| 120 | (2024, MonthOfYear::January, 31), |
| 121 | ]; |
| 122 | |
| 123 | let pattern = res!(FormatPattern::new("MMMM d, yyyy")); |
| 124 | |
| 125 | for (year, month, day) in test_dates { |
| 126 | let date = res!(CalendarDate::from_ymd(year, month, day, zone.clone())); |
| 127 | let time = res!(ClockTime::new(0, 0, 0, 0, zone.clone())); |
| 128 | let clock = res!(CalClock::from_date_time(date, time)); |
| 129 | let formatted = res!(ordinal_formatter.format_with_pattern(&clock, &pattern)); |
| 130 | println!(" {}", formatted); |
| 131 | } |
| 132 | |
| 133 | // Test 5: Week of year and era formatting |
| 134 | println!("\n📆 Test 5: Week of Year and Era"); |
| 135 | |
| 136 | let patterns_advanced = vec![ |
| 137 | ("'Week' w 'of' yyyy", "Week of year"), |
| 138 | ("'Week' ww 'of' yyyy", "2-digit week of year"), |
| 139 | ("yyyy G", "Year with era"), |
| 140 | ("yyyy GGGG", "Year with full era name"), |
| 141 | ("MMMM d, yyyy G", "Date with era"), |
| 142 | ]; |
| 143 | |
| 144 | for (pattern_str, description) in patterns_advanced { |
| 145 | let pattern = res!(FormatPattern::new(pattern_str)); |
| 146 | let formatted = res!(formatter.format_with_pattern(&calclock, &pattern)); |
| 147 | println!(" {} → {}: {}", pattern_str, description, formatted); |
| 148 | } |
| 149 | |
| 150 | // Test 6: Japanese calendar with eras |
| 151 | println!("\n🇯🇵 Test 6: Japanese Calendar with Eras"); |
| 152 | |
| 153 | let japanese_date = res!(CalendarDate::from_ymd(2024, MonthOfYear::June, 15, zone.clone())); |
| 154 | let japanese_time = res!(ClockTime::new(0, 0, 0, 0, zone.clone())); |
| 155 | let japanese_clock = res!(CalClock::from_date_time(japanese_date, japanese_time)); |
| 156 | |
| 157 | let pattern = res!(FormatPattern::new("GGGG yyyy'年'M'月'd'日'")); |
| 158 | let formatted = res!(formatter.format_with_pattern(&japanese_clock, &pattern)); |
| 159 | println!(" Japanese format: {}", formatted); |
| 160 | |
| 161 | // Test historical eras |
| 162 | let historical_dates = vec![ |
| 163 | (1900, "Meiji era"), |
| 164 | (1920, "Taishō era"), |
| 165 | (1950, "Shōwa era"), |
| 166 | (2000, "Heisei era"), |
| 167 | (2020, "Reiwa era"), |
| 168 | ]; |
| 169 | |
| 170 | for (year, expected_era) in historical_dates { |
| 171 | let date = res!(CalendarDate::from_ymd(year, MonthOfYear::January, 1, zone.clone())); |
| 172 | let time = res!(ClockTime::new(0, 0, 0, 0, zone.clone())); |
| 173 | let clock = res!(CalClock::from_date_time(date, time)); |
| 174 | let formatted = res!(formatter.format(&clock, "yyyy GGGG")); |
| 175 | println!(" {}: {} ({})", year, formatted, expected_era); |
| 176 | } |
| 177 | |
| 178 | // Test 7: Complex formatting combinations |
| 179 | println!("\n🎯 Test 7: Complex Formatting"); |
| 180 | |
| 181 | let complex_patterns = vec![ |
| 182 | "'Today is' EEEE, 'the' d 'of' MMMM, yyyy", |
| 183 | "'Quarter' Q 'of' yyyy, 'week' w", |
| 184 | "yyyy-MM-dd'T'HH:mm:ss.SSSZ '['v']'", |
| 185 | "'The time is' h:mm:ss a 'on' EEEE, MMMM d", |
| 186 | ]; |
| 187 | |
| 188 | for pattern_str in complex_patterns { |
| 189 | let pattern = res!(FormatPattern::new(pattern_str)); |
| 190 | let formatted = res!(formatter.format_with_pattern(&calclock, &pattern)); |
| 191 | println!(" {}", formatted); |
| 192 | } |
| 193 | |
| 194 | println!("\n✅ Advanced Formatter Demo completed successfully!"); |
| 195 | println!("🎯 Key features demonstrated:"); |
| 196 | println!(" ✓ Multiple date/time format patterns"); |
| 197 | println!(" ✓ Locale-specific formatting"); |
| 198 | println!(" ✓ Custom month and day name localization"); |
| 199 | println!(" ✓ Ordinal suffixes (1st, 2nd, 3rd)"); |
| 200 | println!(" ✓ Week of year calculation"); |
| 201 | println!(" ✓ Era formatting (CE/BCE, Japanese eras)"); |
| 202 | println!(" ✓ Complex pattern combinations"); |
| 203 | |
| 204 | Ok(()) |
| 205 | } |