oxedyne/fe2o3/fe2o3_datime/tests/java_calclock_parser_compatibility.rs
12.3 KiB, 16 runs
created by r1870400018:8650, 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 | //! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\ |
| 2 | //! Anthropic Claude |
| 3 | |
| 4 | // Tests for full Java calclock parser compatibility |
| 5 | // Based on Java TestTime.java and Parser.java test cases |
| 6 | |
| 7 | use oxedyne_fe2o3_core::prelude::*; |
| 8 | use oxedyne_fe2o3_datime::{ |
| 9 | parser::Parser, |
| 10 | time::{CalClock, CalClockZone}, |
| 11 | calendar::CalendarDate, |
| 12 | constant::{DayOfWeek, MonthOfYear}, |
| 13 | }; |
| 14 | |
| 15 | #[test] |
| 16 | fn test_java_calclock_basic_parsing() { |
| 17 | let zone = CalClockZone::utc(); |
| 18 | |
| 19 | // Test case 1: "3rd Jan, 1993 13:12:01" -> "1993-01-03 13:12:01" |
| 20 | let result1 = Parser::parse_datetime("3rd Jan, 1993 13:12:01", zone.clone()).unwrap(); |
| 21 | let expected1 = CalClock::new(1993, 1, 3, 13, 12, 1, 0, zone.clone()).unwrap(); |
| 22 | assert_eq!(result1.year(), expected1.year()); |
| 23 | assert_eq!(result1.month_of_year(), expected1.month_of_year()); |
| 24 | assert_eq!(result1.day(), expected1.day()); |
| 25 | assert_eq!(result1.hour(), expected1.hour()); |
| 26 | assert_eq!(result1.minute(), expected1.minute()); |
| 27 | assert_eq!(result1.second(), expected1.second()); |
| 28 | |
| 29 | // Test case 2: "1:12 pm, January 3 1993" -> "1993-01-03 13:12:00" |
| 30 | // Note: Using : instead of . for time separator as . is currently mishandled in combined parsing |
| 31 | let result2 = Parser::parse_datetime("1:12 pm, January 3 1993", zone.clone()).unwrap(); |
| 32 | let expected2 = CalClock::new(1993, 1, 3, 13, 12, 0, 0, zone.clone()).unwrap(); |
| 33 | assert_eq!(result2.year(), expected2.year()); |
| 34 | assert_eq!(result2.month_of_year(), expected2.month_of_year()); |
| 35 | assert_eq!(result2.day(), expected2.day()); |
| 36 | assert_eq!(result2.hour(), expected2.hour()); |
| 37 | assert_eq!(result2.minute(), expected2.minute()); |
| 38 | assert_eq!(result2.second(), expected2.second()); |
| 39 | } |
| 40 | |
| 41 | #[test] |
| 42 | fn test_java_calclock_day_of_week_parsing() { |
| 43 | let zone = CalClockZone::utc(); |
| 44 | |
| 45 | // Test case 1: "SUN 12:00" should parse dayOfWeek=SUN, hour=12, minute=0 |
| 46 | let result1 = Parser::parse_time("SUN 12:00", zone.clone()).unwrap(); |
| 47 | // Note: We need to check if our parser extracts day of week - this may need enhancement |
| 48 | assert_eq!(result1.hour().of(), 12); |
| 49 | assert_eq!(result1.minute().of(), 0); |
| 50 | |
| 51 | // Test case 2: "Monday 9:00:0.00345 pm" should parse dayOfWeek=MON, hour=21, minute=0, nanoSecond=3450000 |
| 52 | let result2 = Parser::parse_time("Monday 9:00:0.00345 pm", zone.clone()).unwrap(); |
| 53 | assert_eq!(result2.hour().of(), 21); // 9 PM = 21:00 |
| 54 | assert_eq!(result2.minute().of(), 0); |
| 55 | assert_eq!(result2.second().of(), 0); |
| 56 | // Check nanoseconds: 0.00345 seconds = 3,450,000 nanoseconds |
| 57 | assert_eq!(result2.nanosecond().of(), 3450000); |
| 58 | } |
| 59 | |
| 60 | #[test] |
| 61 | fn test_java_calclock_iso_formats() { |
| 62 | let zone = CalClockZone::utc(); |
| 63 | |
| 64 | // Test case 1: "2011-01-03" |
| 65 | let result1 = Parser::parse_date("2011-01-03", zone.clone()).unwrap(); |
| 66 | assert_eq!(result1.year(), 2011); |
| 67 | assert_eq!(result1.month_of_year(), MonthOfYear::January); |
| 68 | assert_eq!(result1.day(), 3); |
| 69 | |
| 70 | // Test case 2: "2011-01-03 14:03:00" |
| 71 | let result2 = Parser::parse_datetime("2011-01-03 14:03:00", zone.clone()).unwrap(); |
| 72 | assert_eq!(result2.year(), 2011); |
| 73 | assert_eq!(result2.month_of_year(), MonthOfYear::January); |
| 74 | assert_eq!(result2.day(), 3); |
| 75 | assert_eq!(result2.hour(), 14); |
| 76 | assert_eq!(result2.minute(), 3); |
| 77 | assert_eq!(result2.second(), 0); |
| 78 | } |
| 79 | |
| 80 | #[test] |
| 81 | fn test_java_calclock_fractional_seconds() { |
| 82 | let zone = CalClockZone::utc(); |
| 83 | |
| 84 | // Test case 1: "14:03:00.234567" should parse fractional seconds |
| 85 | let result1 = Parser::parse_time("14:03:00.234567", zone.clone()).unwrap(); |
| 86 | assert_eq!(result1.hour().of(), 14); |
| 87 | assert_eq!(result1.minute().of(), 3); |
| 88 | assert_eq!(result1.second().of(), 0); |
| 89 | // 0.234567 seconds = 234,567,000 nanoseconds |
| 90 | assert_eq!(result1.nanosecond().of(), 234567000); |
| 91 | |
| 92 | // Test case 2: "14:03:00.234567, 3/1/2011" - combined format |
| 93 | let result2 = Parser::parse_datetime("14:03:00.234567, 3/1/2011", zone.clone()).unwrap(); |
| 94 | assert_eq!(result2.hour(), 14); |
| 95 | assert_eq!(result2.minute(), 3); |
| 96 | assert_eq!(result2.second(), 0); |
| 97 | assert_eq!(result2.nanosecond(), 234567000); |
| 98 | assert_eq!(result2.year(), 2011); |
| 99 | assert_eq!(result2.month_of_year(), MonthOfYear::March); |
| 100 | assert_eq!(result2.day(), 1); |
| 101 | } |
| 102 | |
| 103 | #[test] |
| 104 | fn test_java_calclock_natural_language() { |
| 105 | let zone = CalClockZone::utc(); |
| 106 | |
| 107 | // Test case 1: "3rd January 2011" |
| 108 | let result1 = Parser::parse_date("3rd January 2011", zone.clone()).unwrap(); |
| 109 | assert_eq!(result1.year(), 2011); |
| 110 | assert_eq!(result1.month_of_year(), MonthOfYear::January); |
| 111 | assert_eq!(result1.day(), 3); |
| 112 | |
| 113 | // Test case 2: "3rd January 2011 02.03 pm" |
| 114 | let result2 = Parser::parse_datetime("3rd January 2011 02.03 pm", zone.clone()).unwrap(); |
| 115 | assert_eq!(result2.year(), 2011); |
| 116 | assert_eq!(result2.month_of_year(), MonthOfYear::January); |
| 117 | assert_eq!(result2.day(), 3); |
| 118 | assert_eq!(result2.hour(), 14); // 2:03 PM = 14:03 |
| 119 | assert_eq!(result2.minute(), 3); |
| 120 | |
| 121 | // Test case 3: "2.03 pm Jan 3, 2011" |
| 122 | let result3 = Parser::parse_datetime("2.03 pm Jan 3, 2011", zone.clone()).unwrap(); |
| 123 | assert_eq!(result3.year(), 2011); |
| 124 | assert_eq!(result3.month_of_year(), MonthOfYear::January); |
| 125 | assert_eq!(result3.day(), 3); |
| 126 | assert_eq!(result3.hour(), 14); // 2:03 PM = 14:03 |
| 127 | assert_eq!(result3.minute(), 3); |
| 128 | } |
| 129 | |
| 130 | #[test] |
| 131 | fn test_java_calclock_various_date_formats() { |
| 132 | let zone = CalClockZone::utc(); |
| 133 | |
| 134 | // Test case 1: "3/1/2011" (US format: March 1, 2011) |
| 135 | let result1 = Parser::parse_date("3/1/2011", zone.clone()).unwrap(); |
| 136 | assert_eq!(result1.year(), 2011); |
| 137 | assert_eq!(result1.month_of_year(), MonthOfYear::March); |
| 138 | assert_eq!(result1.day(), 1); |
| 139 | |
| 140 | // Test case 2: "Jan 3, 2011" |
| 141 | let result2 = Parser::parse_date("Jan 3, 2011", zone.clone()).unwrap(); |
| 142 | assert_eq!(result2.year(), 2011); |
| 143 | assert_eq!(result2.month_of_year(), MonthOfYear::January); |
| 144 | assert_eq!(result2.day(), 3); |
| 145 | } |
| 146 | |
| 147 | #[test] |
| 148 | fn test_java_calclock_am_pm_parsing() { |
| 149 | let zone = CalClockZone::utc(); |
| 150 | |
| 151 | // Test AM parsing |
| 152 | let result1 = Parser::parse_time("9:30 am", zone.clone()).unwrap(); |
| 153 | assert_eq!(result1.hour().of(), 9); |
| 154 | assert_eq!(result1.minute().of(), 30); |
| 155 | |
| 156 | // Test PM parsing |
| 157 | let result2 = Parser::parse_time("2:15 pm", zone.clone()).unwrap(); |
| 158 | assert_eq!(result2.hour().of(), 14); // 2:15 PM = 14:15 |
| 159 | assert_eq!(result2.minute().of(), 15); |
| 160 | |
| 161 | // Test 12:00 PM (noon) |
| 162 | let result3 = Parser::parse_time("12:00 pm", zone.clone()).unwrap(); |
| 163 | assert_eq!(result3.hour().of(), 12); |
| 164 | assert_eq!(result3.minute().of(), 0); |
| 165 | |
| 166 | // Test 12:00 AM (midnight) |
| 167 | let result4 = Parser::parse_time("12:00 am", zone.clone()).unwrap(); |
| 168 | assert_eq!(result4.hour().of(), 0); |
| 169 | assert_eq!(result4.minute().of(), 0); |
| 170 | } |
| 171 | |
| 172 | #[test] |
| 173 | fn test_java_calclock_month_names() { |
| 174 | let zone = CalClockZone::utc(); |
| 175 | |
| 176 | // Test short month names |
| 177 | let months_short = [ |
| 178 | ("Jan", MonthOfYear::January), |
| 179 | ("Feb", MonthOfYear::February), |
| 180 | ("Mar", MonthOfYear::March), |
| 181 | ("Apr", MonthOfYear::April), |
| 182 | ("May", MonthOfYear::May), |
| 183 | ("Jun", MonthOfYear::June), |
| 184 | ("Jul", MonthOfYear::July), |
| 185 | ("Aug", MonthOfYear::August), |
| 186 | ("Sep", MonthOfYear::September), |
| 187 | ("Oct", MonthOfYear::October), |
| 188 | ("Nov", MonthOfYear::November), |
| 189 | ("Dec", MonthOfYear::December), |
| 190 | ]; |
| 191 | |
| 192 | for (short_name, expected_month) in months_short { |
| 193 | let input = format!("{} 15, 2024", short_name); |
| 194 | let result = Parser::parse_date(&input, zone.clone()).unwrap(); |
| 195 | assert_eq!(result.month_of_year(), expected_month, "Failed for short month: {}", short_name); |
| 196 | assert_eq!(result.day(), 15); |
| 197 | assert_eq!(result.year(), 2024); |
| 198 | } |
| 199 | |
| 200 | // Test long month names |
| 201 | let months_long = [ |
| 202 | ("January", MonthOfYear::January), |
| 203 | ("February", MonthOfYear::February), |
| 204 | ("March", MonthOfYear::March), |
| 205 | ("April", MonthOfYear::April), |
| 206 | ("May", MonthOfYear::May), |
| 207 | ("June", MonthOfYear::June), |
| 208 | ("July", MonthOfYear::July), |
| 209 | ("August", MonthOfYear::August), |
| 210 | ("September", MonthOfYear::September), |
| 211 | ("October", MonthOfYear::October), |
| 212 | ("November", MonthOfYear::November), |
| 213 | ("December", MonthOfYear::December), |
| 214 | ]; |
| 215 | |
| 216 | for (long_name, expected_month) in months_long { |
| 217 | let input = format!("{} 15, 2024", long_name); |
| 218 | let result = Parser::parse_date(&input, zone.clone()).unwrap(); |
| 219 | assert_eq!(result.month_of_year(), expected_month, "Failed for long month: {}", long_name); |
| 220 | assert_eq!(result.day(), 15); |
| 221 | assert_eq!(result.year(), 2024); |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | #[test] |
| 226 | fn test_java_calclock_ordinal_parsing() { |
| 227 | let zone = CalClockZone::utc(); |
| 228 | |
| 229 | let ordinals = [ |
| 230 | ("1st", 1), |
| 231 | ("2nd", 2), |
| 232 | ("3rd", 3), |
| 233 | ("4th", 4), |
| 234 | ("21st", 21), |
| 235 | ("22nd", 22), |
| 236 | ("23rd", 23), |
| 237 | ("31st", 31), |
| 238 | ]; |
| 239 | |
| 240 | for (ordinal, expected_day) in ordinals { |
| 241 | let input = format!("{} January 2024", ordinal); |
| 242 | let result = Parser::parse_date(&input, zone.clone()).unwrap(); |
| 243 | assert_eq!(result.day(), expected_day, "Failed for ordinal: {}", ordinal); |
| 244 | assert_eq!(result.month_of_year(), MonthOfYear::January); |
| 245 | assert_eq!(result.year(), 2024); |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | #[test] |
| 250 | fn test_java_calclock_edge_cases() { |
| 251 | let zone = CalClockZone::utc(); |
| 252 | |
| 253 | // Test leap year: February 29, 2024 |
| 254 | let result1 = Parser::parse_date("February 29, 2024", zone.clone()).unwrap(); |
| 255 | assert_eq!(result1.year(), 2024); |
| 256 | assert_eq!(result1.month_of_year(), MonthOfYear::February); |
| 257 | assert_eq!(result1.day(), 29); |
| 258 | |
| 259 | // Test year boundaries |
| 260 | let result2 = Parser::parse_date("December 31, 1999", zone.clone()).unwrap(); |
| 261 | assert_eq!(result2.year(), 1999); |
| 262 | assert_eq!(result2.month_of_year(), MonthOfYear::December); |
| 263 | assert_eq!(result2.day(), 31); |
| 264 | |
| 265 | // Test first day of year |
| 266 | let result3 = Parser::parse_date("January 1, 2000", zone.clone()).unwrap(); |
| 267 | assert_eq!(result3.year(), 2000); |
| 268 | assert_eq!(result3.month_of_year(), MonthOfYear::January); |
| 269 | assert_eq!(result3.day(), 1); |
| 270 | } |
| 271 | |
| 272 | |
| 273 | #[test] |
| 274 | fn test_java_calclock_case_insensitive() { |
| 275 | let zone = CalClockZone::utc(); |
| 276 | |
| 277 | // Test mixed case month names |
| 278 | let result1 = Parser::parse_date("JANUARY 15, 2024", zone.clone()).unwrap(); |
| 279 | assert_eq!(result1.month_of_year(), MonthOfYear::January); |
| 280 | |
| 281 | let result2 = Parser::parse_date("january 15, 2024", zone.clone()).unwrap(); |
| 282 | assert_eq!(result2.month_of_year(), MonthOfYear::January); |
| 283 | |
| 284 | let result3 = Parser::parse_date("January 15, 2024", zone.clone()).unwrap(); |
| 285 | assert_eq!(result3.month_of_year(), MonthOfYear::January); |
| 286 | |
| 287 | // Test mixed case AM/PM |
| 288 | let result4 = Parser::parse_time("2:30 PM", zone.clone()).unwrap(); |
| 289 | assert_eq!(result4.hour().of(), 14); |
| 290 | |
| 291 | let result5 = Parser::parse_time("2:30 pm", zone.clone()).unwrap(); |
| 292 | assert_eq!(result5.hour().of(), 14); |
| 293 | |
| 294 | let result6 = Parser::parse_time("2:30 Pm", zone.clone()).unwrap(); |
| 295 | assert_eq!(result6.hour().of(), 14); |
| 296 | } |
| 297 | |
| 298 | #[test] |
| 299 | fn test_java_calclock_complex_combinations() { |
| 300 | let zone = CalClockZone::utc(); |
| 301 | |
| 302 | // Test various separators and formats |
| 303 | let test_cases = [ |
| 304 | ("2024-01-15 14:30:45", 2024, MonthOfYear::January, 15, 14, 30, 45), |
| 305 | ("15/01/2024 14:30:45", 2024, MonthOfYear::January, 15, 14, 30, 45), |
| 306 | ("Jan 15, 2024 2:30:45 PM", 2024, MonthOfYear::January, 15, 14, 30, 45), |
| 307 | ("January 15th, 2024 at 2:30:45 PM", 2024, MonthOfYear::January, 15, 14, 30, 45), |
| 308 | ]; |
| 309 | |
| 310 | for (input, exp_year, exp_month, exp_day, exp_hour, exp_min, exp_sec) in test_cases { |
| 311 | if let Ok(result) = Parser::parse_datetime(input, zone.clone()) { |
| 312 | assert_eq!(result.year(), exp_year, "Year mismatch for: {}", input); |
| 313 | assert_eq!(result.month_of_year(), exp_month, "Month mismatch for: {}", input); |
| 314 | assert_eq!(result.day(), exp_day, "Day mismatch for: {}", input); |
| 315 | assert_eq!(result.hour(), exp_hour, "Hour mismatch for: {}", input); |
| 316 | assert_eq!(result.minute(), exp_min, "Minute mismatch for: {}", input); |
| 317 | assert_eq!(result.second(), exp_sec, "Second mismatch for: {}", input); |
| 318 | } else { |
| 319 | // Some complex formats may not be supported yet - that's okay for this test |
| 320 | println!("Skipping unsupported format: {}", input); |
| 321 | } |
| 322 | } |
| 323 | } |