3
3
//! The goal of the calendar module of `boa_temporal` is to provide
4
4
//! Temporal compatible calendar implementations.
5
5
6
- // TODO: It may finally be time to clean up API to use `IsoDate` and `DateDuration` directly.
7
-
8
- use alloc:: string:: String ;
9
- use alloc:: vec:: Vec ;
10
- use core:: str:: FromStr ;
11
- use icu_calendar:: types:: { Era as IcuEra , MonthCode as IcuMonthCode , MonthInfo , YearInfo } ;
12
-
13
6
use crate :: {
14
7
builtins:: core:: {
15
8
duration:: { DateDuration , TimeDuration } ,
@@ -20,7 +13,9 @@ use crate::{
20
13
parsers:: parse_allowed_calendar_formats,
21
14
TemporalError , TemporalResult ,
22
15
} ;
16
+ use core:: str:: FromStr ;
23
17
18
+ use icu_calendar:: types:: { Era as IcuEra , MonthCode as IcuMonthCode , MonthInfo , YearInfo } ;
24
19
use icu_calendar:: {
25
20
any_calendar:: AnyDateInner ,
26
21
cal:: {
@@ -40,8 +35,8 @@ use super::{PartialDate, ZonedDateTime};
40
35
mod era;
41
36
mod types;
42
37
43
- pub use types:: ResolvedCalendarFields ;
44
- pub ( crate ) use types:: { ascii_four_to_integer , month_to_month_code } ;
38
+ pub ( crate ) use types:: { month_to_month_code , ResolutionType } ;
39
+ pub use types:: { MonthCode , ResolvedCalendarFields } ;
45
40
46
41
use era:: EraInfo ;
47
42
@@ -226,13 +221,14 @@ impl Calendar {
226
221
partial : & PartialDate ,
227
222
overflow : ArithmeticOverflow ,
228
223
) -> TemporalResult < PlainDate > {
229
- let resolved_fields = ResolvedCalendarFields :: try_from_partial ( partial, overflow) ?;
224
+ let resolved_fields =
225
+ ResolvedCalendarFields :: try_from_partial ( partial, overflow, ResolutionType :: Date ) ?;
230
226
231
227
if self . is_iso ( ) {
232
228
// Resolve month and monthCode;
233
229
return PlainDate :: new_with_overflow (
234
230
resolved_fields. era_year . year ,
235
- resolved_fields. month_code . as_iso_month_integer ( ) ? ,
231
+ resolved_fields. month_code . to_month_integer ( ) ,
236
232
resolved_fields. day ,
237
233
self . clone ( ) ,
238
234
overflow,
@@ -264,10 +260,11 @@ impl Calendar {
264
260
partial : & PartialDate ,
265
261
overflow : ArithmeticOverflow ,
266
262
) -> TemporalResult < PlainMonthDay > {
267
- let resolved_fields = ResolvedCalendarFields :: try_from_partial ( partial, overflow) ?;
263
+ let resolved_fields =
264
+ ResolvedCalendarFields :: try_from_partial ( partial, overflow, ResolutionType :: MonthDay ) ?;
268
265
if self . is_iso ( ) {
269
266
return PlainMonthDay :: new_with_overflow (
270
- resolved_fields. month_code . as_iso_month_integer ( ) ? ,
267
+ resolved_fields. month_code . to_month_integer ( ) ,
271
268
resolved_fields. day ,
272
269
self . clone ( ) ,
273
270
overflow,
@@ -286,11 +283,12 @@ impl Calendar {
286
283
partial : & PartialDate ,
287
284
overflow : ArithmeticOverflow ,
288
285
) -> TemporalResult < PlainYearMonth > {
289
- let resolved_fields = ResolvedCalendarFields :: try_from_partial ( partial, overflow) ?;
286
+ let resolved_fields =
287
+ ResolvedCalendarFields :: try_from_partial ( partial, overflow, ResolutionType :: YearMonth ) ?;
290
288
if self . is_iso ( ) {
291
289
return PlainYearMonth :: new_with_overflow (
292
290
resolved_fields. era_year . year ,
293
- resolved_fields. month_code . as_iso_month_integer ( ) ? ,
291
+ resolved_fields. month_code . to_month_integer ( ) ,
294
292
Some ( resolved_fields. day ) ,
295
293
self . clone ( ) ,
296
294
overflow,
@@ -360,7 +358,6 @@ impl Calendar {
360
358
let date_duration = one. diff_iso_date ( two, largest_unit) ?;
361
359
return Ok ( Duration :: from ( date_duration) ) ;
362
360
}
363
-
364
361
Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
365
362
}
366
363
@@ -396,56 +393,57 @@ impl Calendar {
396
393
if self . is_iso ( ) {
397
394
return Ok ( iso_date. month ) ;
398
395
}
399
-
400
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
396
+ let calendar_date = self . 0 . date_from_iso ( iso_date . as_icu4x ( ) ? ) ;
397
+ Ok ( self . 0 . month ( & calendar_date ) . month_number ( ) )
401
398
}
402
399
403
400
/// `CalendarMonthCode`
404
- pub fn month_code ( & self , iso_date : & IsoDate ) -> TemporalResult < TinyAsciiStr < 4 > > {
401
+ pub fn month_code ( & self , iso_date : & IsoDate ) -> TemporalResult < MonthCode > {
405
402
if self . is_iso ( ) {
406
- return Ok ( iso_date. as_icu4x ( ) ?. month ( ) . standard_code . 0 ) ;
403
+ let mc = iso_date. as_icu4x ( ) ?. month ( ) . standard_code . 0 ;
404
+ return Ok ( MonthCode ( mc) ) ;
407
405
}
408
-
409
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
406
+ let calendar_date = self . 0 . date_from_iso ( iso_date . as_icu4x ( ) ? ) ;
407
+ Ok ( MonthCode ( self . 0 . month ( & calendar_date ) . standard_code . 0 ) )
410
408
}
411
409
412
410
/// `CalendarDay`
413
411
pub fn day ( & self , iso_date : & IsoDate ) -> TemporalResult < u8 > {
414
412
if self . is_iso ( ) {
415
413
return Ok ( iso_date. day ) ;
416
414
}
417
-
418
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
415
+ let calendar_date = self . 0 . date_from_iso ( iso_date . as_icu4x ( ) ? ) ;
416
+ Ok ( self . 0 . day_of_month ( & calendar_date ) . 0 )
419
417
}
420
418
421
419
/// `CalendarDayOfWeek`
422
420
pub fn day_of_week ( & self , iso_date : & IsoDate ) -> TemporalResult < u16 > {
423
421
if self . is_iso ( ) {
424
422
return Ok ( iso_date. as_icu4x ( ) ?. day_of_week ( ) as u16 ) ;
425
423
}
426
-
427
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
424
+ let calendar_date = self . 0 . date_from_iso ( iso_date. as_icu4x ( ) ?) ;
425
+ // TODO: Understand ICU4X's decision for `IsoWeekDay` to be `i8`
426
+ Ok ( self . 0 . day_of_week ( & calendar_date) as u16 )
428
427
}
429
428
430
429
/// `CalendarDayOfYear`
431
430
pub fn day_of_year ( & self , iso_date : & IsoDate ) -> TemporalResult < u16 > {
432
431
if self . is_iso ( ) {
433
432
return Ok ( iso_date. as_icu4x ( ) ?. day_of_year_info ( ) . day_of_year ) ;
434
433
}
435
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) ) ?
434
+ let calendar_date = self . 0 . date_from_iso ( iso_date. as_icu4x ( ) ?) ;
435
+ Ok ( self . 0 . day_of_year_info ( & calendar_date) . day_of_year )
436
436
}
437
437
438
438
/// `CalendarWeekOfYear`
439
439
pub fn week_of_year ( & self , iso_date : & IsoDate ) -> TemporalResult < Option < u16 > > {
440
440
if self . is_iso ( ) {
441
441
let date = iso_date. as_icu4x ( ) ?;
442
-
443
442
let week_calculator = WeekCalculator :: default ( ) ;
444
-
445
443
let week_of = date. week_of_year ( & week_calculator) ;
446
-
447
444
return Ok ( Some ( week_of. week as u16 ) ) ;
448
445
}
446
+ // TODO: Research in ICU4X and determine best approach.
449
447
Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
450
448
}
451
449
@@ -464,6 +462,7 @@ impl Calendar {
464
462
RelativeUnit :: Next => Ok ( Some ( date. year ( ) . extended_year + 1 ) ) ,
465
463
} ;
466
464
}
465
+ // TODO: Research in ICU4X and determine best approach.
467
466
Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
468
467
}
469
468
@@ -472,6 +471,7 @@ impl Calendar {
472
471
if self . is_iso ( ) {
473
472
return Ok ( 7 ) ;
474
473
}
474
+ // TODO: Research in ICU4X and determine best approach.
475
475
Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
476
476
}
477
477
@@ -480,40 +480,35 @@ impl Calendar {
480
480
if self . is_iso ( ) {
481
481
return Ok ( iso_date. as_icu4x ( ) ?. days_in_month ( ) as u16 ) ;
482
482
}
483
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
483
+ let calendar_date = self . 0 . date_from_iso ( iso_date. as_icu4x ( ) ?) ;
484
+ Ok ( self . 0 . days_in_month ( & calendar_date) as u16 )
484
485
}
485
486
486
487
/// `CalendarDaysInYear`
487
488
pub fn days_in_year ( & self , iso_date : & IsoDate ) -> TemporalResult < u16 > {
488
489
if self . is_iso ( ) {
489
490
return Ok ( iso_date. as_icu4x ( ) ?. days_in_year ( ) ) ;
490
491
}
491
-
492
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
492
+ let calendar_date = self . 0 . date_from_iso ( iso_date . as_icu4x ( ) ? ) ;
493
+ Ok ( self . 0 . days_in_year ( & calendar_date ) )
493
494
}
494
495
495
496
/// `CalendarMonthsInYear`
496
- pub fn months_in_year ( & self , _iso_date : & IsoDate ) -> TemporalResult < u16 > {
497
+ pub fn months_in_year ( & self , iso_date : & IsoDate ) -> TemporalResult < u16 > {
497
498
if self . is_iso ( ) {
498
499
return Ok ( 12 ) ;
499
500
}
500
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
501
+ let calendar_date = self . 0 . date_from_iso ( iso_date. as_icu4x ( ) ?) ;
502
+ Ok ( self . 0 . months_in_year ( & calendar_date) as u16 )
501
503
}
502
504
503
505
/// `CalendarInLeapYear`
504
506
pub fn in_leap_year ( & self , iso_date : & IsoDate ) -> TemporalResult < bool > {
505
507
if self . is_iso ( ) {
506
508
return Ok ( iso_date. as_icu4x ( ) ?. is_in_leap_year ( ) ) ;
507
509
}
508
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
509
- }
510
-
511
- /// `CalendarFields`
512
- pub fn fields ( & self , fields : Vec < String > ) -> TemporalResult < Vec < String > > {
513
- if self . is_iso ( ) {
514
- return Ok ( fields) ;
515
- }
516
- Err ( TemporalError :: range ( ) . with_message ( "Not yet implemented." ) )
510
+ let calendar_date = self . 0 . date_from_iso ( iso_date. as_icu4x ( ) ?) ;
511
+ Ok ( self . 0 . is_in_leap_year ( & calendar_date) )
517
512
}
518
513
519
514
/// Returns the identifier of this calendar slot.
0 commit comments