12
12
//! .expect("Failed to initialize Chinese Date instance.");
13
13
//!
14
14
//! assert_eq!(chinese_date.cyclic_year().related_iso, 2023);
15
- //! assert_eq!(chinese_date.cyclic_year().year.get() , 40);
15
+ //! assert_eq!(chinese_date.cyclic_year().year, 40);
16
16
//! assert_eq!(chinese_date.month().ordinal, 6);
17
17
//! assert_eq!(chinese_date.day_of_month().0, 6);
18
18
//! ```
19
19
20
- use crate :: cal:: chinese_based:: {
21
- chinese_based_ordinal_lunar_month_from_code, ChineseBasedDateInner ,
22
- ChineseBasedPrecomputedData , ChineseBasedWithDataLoading ,
23
- } ;
20
+ use crate :: cal:: chinese_based:: { ChineseBasedPrecomputedData , ChineseBasedWithDataLoading } ;
24
21
use crate :: cal:: iso:: { Iso , IsoDateInner } ;
25
- use crate :: calendar_arithmetic:: CalendarArithmetic ;
26
22
use crate :: calendar_arithmetic:: PrecomputedDataSource ;
23
+ use crate :: calendar_arithmetic:: { ArithmeticDate , CalendarArithmetic } ;
27
24
use crate :: error:: DateError ;
28
25
use crate :: provider:: chinese_based:: CalendarChineseV1 ;
29
26
use crate :: AsCalendar ;
30
27
use crate :: { types, Calendar , Date , DateDuration , DateDurationUnit } ;
31
28
use calendrical_calculations:: chinese_based:: { self , ChineseBased } ;
32
29
use calendrical_calculations:: rata_die:: RataDie ;
33
30
use core:: cmp:: Ordering ;
34
- use core:: num:: NonZeroU8 ;
35
31
use icu_provider:: prelude:: * ;
36
32
37
33
/// The [Chinese Calendar](https://en.wikipedia.org/wiki/Chinese_calendar)
@@ -84,9 +80,7 @@ pub struct Chinese {
84
80
85
81
/// The inner date type used for representing [`Date`]s of [`Chinese`]. See [`Date`] and [`Chinese`] for more details.
86
82
#[ derive( Debug , Eq , PartialEq , PartialOrd , Ord ) ]
87
- pub struct ChineseDateInner ( ChineseBasedDateInner < Chinese > ) ;
88
-
89
- type Inner = ChineseBasedDateInner < Chinese > ;
83
+ pub struct ChineseDateInner ( ArithmeticDate < Chinese > ) ;
90
84
91
85
// we want these impls without the `C: Copy/Clone` bounds
92
86
impl Copy for ChineseDateInner { }
@@ -169,37 +163,44 @@ impl Calendar for Chinese {
169
163
month_code : types:: MonthCode ,
170
164
day : u8 ,
171
165
) -> Result < Self :: DateInner , DateError > {
166
+ match era {
167
+ None => { }
168
+ _ => return Err ( DateError :: UnknownEra ) ,
169
+ }
170
+
172
171
let year = self . get_precomputed_data ( ) . load_or_compute_info ( year) ;
173
172
174
- let Some ( month) = chinese_based_ordinal_lunar_month_from_code ( month_code, year ) else {
173
+ let Some ( month) = year . parse_month_code ( month_code) else {
175
174
return Err ( DateError :: UnknownMonthCode ( month_code) ) ;
176
175
} ;
177
176
178
- match era {
179
- None => { }
180
- _ => return Err ( DateError :: UnknownEra ) ,
181
- }
177
+ year. validate_md ( month, day) ?;
182
178
183
- Inner :: new_from_ordinals ( year , month , day )
184
- . map ( ChineseBasedDateInner )
185
- . map ( ChineseDateInner )
179
+ Ok ( ChineseDateInner ( ArithmeticDate :: new_unchecked (
180
+ year , month , day ,
181
+ ) ) )
186
182
}
187
183
188
184
fn from_rata_die ( & self , rd : RataDie ) -> Self :: DateInner {
189
185
let iso = Iso . from_rata_die ( rd) ;
190
- ChineseDateInner ( Inner :: chinese_based_date_from_rd ( self , rd, iso. 0 ) )
186
+ let y = self
187
+ . get_precomputed_data ( )
188
+ . load_or_compute_info_for_rd ( rd, iso. 0 ) ;
189
+ let ( m, d) = y. md_from_rd ( rd) ;
190
+ ChineseDateInner ( ArithmeticDate :: new_unchecked ( y, m, d) )
191
191
}
192
192
193
193
fn to_rata_die ( & self , date : & Self :: DateInner ) -> RataDie {
194
- Inner :: rd_from_chinese_based_date_inner ( date. 0 )
194
+ date . 0 . year . rd_from_md ( date. 0 . month , date . 0 . day )
195
195
}
196
196
197
197
fn from_iso ( & self , iso : IsoDateInner ) -> Self :: DateInner {
198
- ChineseDateInner ( Inner :: chinese_based_date_from_rd (
199
- self ,
200
- Iso . to_rata_die ( & iso) ,
201
- iso. 0 ,
202
- ) )
198
+ let rd = Iso . to_rata_die ( & iso) ;
199
+ let y = self
200
+ . get_precomputed_data ( )
201
+ . load_or_compute_info_for_rd ( rd, iso. 0 ) ;
202
+ let ( m, d) = y. md_from_rd ( rd) ;
203
+ ChineseDateInner ( ArithmeticDate :: new_unchecked ( y, m, d) )
203
204
}
204
205
205
206
fn to_iso ( & self , date : & Self :: DateInner ) -> IsoDateInner {
@@ -209,16 +210,16 @@ impl Calendar for Chinese {
209
210
// Count the number of months in a given year, specified by providing a date
210
211
// from that year
211
212
fn days_in_year ( & self , date : & Self :: DateInner ) -> u16 {
212
- date. 0 . days_in_year_inner ( )
213
+ date. 0 . days_in_year ( )
213
214
}
214
215
215
216
fn days_in_month ( & self , date : & Self :: DateInner ) -> u8 {
216
- date. 0 . days_in_month_inner ( )
217
+ date. 0 . days_in_month ( )
217
218
}
218
219
219
220
#[ doc( hidden) ] // unstable
220
221
fn offset_date ( & self , date : & mut Self :: DateInner , offset : DateDuration < Self > ) {
221
- date. 0 . 0 . offset_date ( offset, & self . get_precomputed_data ( ) ) ;
222
+ date. 0 . offset_date ( offset, & self . get_precomputed_data ( ) ) ;
222
223
}
223
224
224
225
#[ doc( hidden) ] // unstable
@@ -235,7 +236,7 @@ impl Calendar for Chinese {
235
236
_largest_unit : DateDurationUnit ,
236
237
_smallest_unit : DateDurationUnit ,
237
238
) -> DateDuration < Self > {
238
- date1. 0 . 0 . until ( date2. 0 . 0 , _largest_unit, _smallest_unit)
239
+ date1. 0 . until ( date2. 0 , _largest_unit, _smallest_unit)
239
240
}
240
241
241
242
/// Obtain a name for the calendar for debug printing
@@ -244,47 +245,45 @@ impl Calendar for Chinese {
244
245
}
245
246
246
247
fn year_info ( & self , date : & Self :: DateInner ) -> Self :: Year {
247
- let year = date. 0 . 0 . year ;
248
- let cyclic = ( year. related_iso - 4 ) . rem_euclid ( 60 ) as u8 ;
249
- let cyclic = NonZeroU8 :: new ( cyclic + 1 ) . unwrap_or ( NonZeroU8 :: MIN ) ; // 1-indexed
248
+ let year = date. 0 . year ;
250
249
types:: CyclicYear {
251
- year : cyclic ,
250
+ year : ( year . related_iso - 4 ) . rem_euclid ( 60 ) as u8 + 1 ,
252
251
related_iso : year. related_iso ,
253
252
}
254
253
}
255
254
256
255
fn extended_year ( & self , date : & Self :: DateInner ) -> i32 {
257
- chinese_based:: Chinese :: extended_from_iso ( date. 0 . 0 . year . related_iso )
256
+ chinese_based:: Chinese :: extended_from_iso ( date. 0 . year . related_iso )
258
257
}
259
258
260
259
fn is_in_leap_year ( & self , date : & Self :: DateInner ) -> bool {
261
- Self :: provided_year_is_leap ( date. 0 . 0 . year )
260
+ Self :: provided_year_is_leap ( date. 0 . year )
262
261
}
263
262
264
263
/// The calendar-specific month code represented by `date`;
265
264
/// since the Chinese calendar has leap months, an "L" is appended to the month code for
266
265
/// leap months. For example, in a year where an intercalary month is added after the second
267
266
/// month, the month codes for ordinal months 1, 2, 3, 4, 5 would be "M01", "M02", "M02L", "M03", "M04".
268
267
fn month ( & self , date : & Self :: DateInner ) -> types:: MonthInfo {
269
- date. 0 . month ( )
268
+ date. 0 . year . month ( date . 0 . month )
270
269
}
271
270
272
271
/// The calendar-specific day-of-month represented by `date`
273
272
fn day_of_month ( & self , date : & Self :: DateInner ) -> types:: DayOfMonth {
274
- types :: DayOfMonth ( date. 0 . 0 . day )
273
+ date. 0 . day_of_month ( )
275
274
}
276
275
277
276
/// Information of the day of the year
278
277
fn day_of_year ( & self , date : & Self :: DateInner ) -> types:: DayOfYear {
279
- types:: DayOfYear ( date. 0 . day_of_year ( ) )
278
+ types:: DayOfYear ( date. 0 . year . day_of_year ( date . 0 . month , date . 0 . day ) )
280
279
}
281
280
282
281
fn any_calendar_kind ( & self ) -> Option < crate :: AnyCalendarKind > {
283
282
Some ( crate :: any_calendar:: IntoAnyCalendar :: kind ( self ) )
284
283
}
285
284
286
285
fn months_in_year ( & self , date : & Self :: DateInner ) -> u8 {
287
- date. 0 . months_in_year_inner ( )
286
+ date. 0 . months_in_year ( )
288
287
}
289
288
}
290
289
@@ -307,7 +306,7 @@ impl<A: AsCalendar<Calendar = Chinese>> Date<A> {
307
306
/// .expect("Failed to initialize Chinese Date instance.");
308
307
///
309
308
/// assert_eq!(date_chinese.cyclic_year().related_iso, 2023);
310
- /// assert_eq!(date_chinese.cyclic_year().year.get() , 40);
309
+ /// assert_eq!(date_chinese.cyclic_year().year, 40);
311
310
/// assert_eq!(date_chinese.month().ordinal, 6);
312
311
/// assert_eq!(date_chinese.day_of_month().0, 11);
313
312
/// ```
@@ -321,9 +320,9 @@ impl<A: AsCalendar<Calendar = Chinese>> Date<A> {
321
320
. as_calendar ( )
322
321
. get_precomputed_data ( )
323
322
. load_or_compute_info ( related_iso_year) ;
324
- let arithmetic = Inner :: new_from_ordinals ( year, month, day) ;
323
+ year. validate_md ( month, day) ? ;
325
324
Ok ( Date :: from_raw (
326
- ChineseDateInner ( ChineseBasedDateInner ( arithmetic? ) ) ,
325
+ ChineseDateInner ( ArithmeticDate :: new_unchecked ( year , month , day ) ) ,
327
326
calendar,
328
327
) )
329
328
}
@@ -518,9 +517,9 @@ mod test {
518
517
case. year , case. month , case. day , chinese,
519
518
)
520
519
. unwrap ( ) ;
521
- let rd = Inner :: rd_from_chinese_based_date_inner ( date. inner . 0 ) . to_i64_date ( ) ;
520
+ let rd = date. to_rata_die ( ) . to_i64_date ( ) ;
522
521
let expected = case. expected ;
523
- assert_eq ! ( rd, expected, "[{calendar_type}] RD from Chinese failed, with expected: {rd } and calculated: {expected }, for test case: {case:?}" ) ;
522
+ assert_eq ! ( rd, expected, "[{calendar_type}] RD from Chinese failed, with expected: {expected } and calculated: {rd }, for test case: {case:?}" ) ;
524
523
} ,
525
524
) ;
526
525
}
@@ -536,16 +535,14 @@ mod test {
536
535
let chinese_cached = Chinese :: new ( ) ;
537
536
while rd < max_rd && iters < max_iters {
538
537
let rata_die = RataDie :: new ( rd) ;
539
- let iso = Iso . from_rata_die ( rata_die) ;
540
538
541
539
do_twice (
542
540
& chinese_calculating,
543
541
& chinese_cached,
544
542
|chinese, calendar_type| {
545
- let chinese = Inner :: chinese_based_date_from_rd ( & chinese, rata_die, iso. 0 ) ;
546
- let result = Inner :: rd_from_chinese_based_date_inner ( chinese) ;
547
- let result_debug = result. to_i64_date ( ) ;
548
- assert_eq ! ( result, rata_die, "[{calendar_type}] Failed roundtrip RD -> Chinese -> RD for RD: {rd}, with calculated: {result_debug} from Chinese date:\n {chinese:?}" ) ;
543
+ let chinese = Date :: from_rata_die ( rata_die, chinese) ;
544
+ let result = chinese. to_rata_die ( ) ;
545
+ assert_eq ! ( result, rata_die, "[{calendar_type}] Failed roundtrip RD -> Chinese -> RD for RD: {rata_die:?}, with calculated: {result:?} from Chinese date:\n {chinese:?}" ) ;
549
546
} ,
550
547
) ;
551
548
rd += 7043 ;
@@ -567,7 +564,7 @@ mod test {
567
564
assert_eq ! ( chinese. month( ) . ordinal, 1 ) ;
568
565
assert_eq ! ( chinese. month( ) . standard_code. 0 , "M01" ) ;
569
566
assert_eq ! ( chinese. day_of_month( ) . 0 , 1 ) ;
570
- assert_eq ! ( chinese. cyclic_year( ) . year. get ( ) , 1 ) ;
567
+ assert_eq ! ( chinese. cyclic_year( ) . year, 1 ) ;
571
568
assert_eq ! ( chinese. cyclic_year( ) . related_iso, -2636 ) ;
572
569
} ,
573
570
)
@@ -660,7 +657,7 @@ mod test {
660
657
chinese_date. is_in_leap_year( ) ,
661
658
"[{calendar_type}] {year} should be a leap year"
662
659
) ;
663
- let new_year = chinese_date. inner . 0 . new_year ( ) ;
660
+ let new_year = chinese_date. inner . 0 . year . new_year ( ) ;
664
661
assert_eq ! (
665
662
expected_month,
666
663
calendrical_calculations:: chinese_based:: get_leap_month_from_new_year:: <
@@ -849,7 +846,7 @@ mod test {
849
846
] ;
850
847
for ordinal_code_pair in codes {
851
848
let code = MonthCode ( ordinal_code_pair. 1 ) ;
852
- let ordinal = chinese_based_ordinal_lunar_month_from_code ( code, year ) ;
849
+ let ordinal = year . parse_month_code ( code) ;
853
850
assert_eq ! (
854
851
ordinal,
855
852
Some ( ordinal_code_pair. 0 ) ,
@@ -880,7 +877,7 @@ mod test {
880
877
> :: default ( )
881
878
. load_or_compute_info ( year) ;
882
879
let code = MonthCode ( code) ;
883
- let ordinal = chinese_based_ordinal_lunar_month_from_code ( code, year ) ;
880
+ let ordinal = year . parse_month_code ( code) ;
884
881
assert_eq ! (
885
882
ordinal, None ,
886
883
"Invalid month code failed for year: {}, code: {code}" ,
@@ -1023,8 +1020,7 @@ mod test {
1023
1020
"[{calendar_type}] Related ISO failed for test case: {case:?}"
1024
1021
) ;
1025
1022
assert_eq ! (
1026
- chinese_cyclic. get( ) ,
1027
- case. expected_cyclic,
1023
+ chinese_cyclic, case. expected_cyclic,
1028
1024
"[{calendar_type}] Cyclic year failed for test case: {case:?}"
1029
1025
) ;
1030
1026
assert_eq ! (
0 commit comments