3
3
use tinystr:: TinyAsciiStr ;
4
4
5
5
use crate :: {
6
- components:: { calendar:: Calendar , tz:: TimeZone , Instant } ,
7
- iso:: IsoDateTime ,
6
+ components:: { calendar:: Calendar , duration :: normalized :: NormalizedTimeDuration , tz:: TimeZone , Instant } ,
7
+ iso:: { IsoDate , IsoDateTime } ,
8
8
options:: { ArithmeticOverflow , Disambiguation } ,
9
9
Sign , TemporalError , TemporalResult ,
10
10
} ;
@@ -78,7 +78,7 @@ impl ZonedDateTime {
78
78
. with_message ( "Intermediate ISO datetime was not within a valid range." ) ) ;
79
79
}
80
80
// 6. Let intermediateNs be ! GetEpochNanosecondsFor(timeZone, intermediateDateTime, compatible).
81
- let intermediate_ns = self . tz ( ) . get_epoch_nanoseconds_for (
81
+ let intermediate_ns = self . timezone ( ) . get_epoch_nanoseconds_for (
82
82
intermediate,
83
83
Disambiguation :: Compatible ,
84
84
provider,
@@ -113,7 +113,7 @@ impl ZonedDateTime {
113
113
. add_as_instant ( duration, overflow, provider) ?
114
114
. epoch_nanos ;
115
115
// 9. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar).
116
- Self :: try_new ( epoch_ns, self . calendar ( ) . clone ( ) , self . tz ( ) . clone ( ) )
116
+ Self :: try_new ( epoch_ns, self . calendar ( ) . clone ( ) , self . timezone ( ) . clone ( ) )
117
117
}
118
118
}
119
119
@@ -137,7 +137,7 @@ impl ZonedDateTime {
137
137
/// Returns `ZonedDateTime`'s `TimeZone` slot.
138
138
#[ inline]
139
139
#[ must_use]
140
- pub fn tz ( & self ) -> & TimeZone {
140
+ pub fn timezone ( & self ) -> & TimeZone {
141
141
& self . tz
142
142
}
143
143
@@ -166,7 +166,7 @@ impl ZonedDateTime {
166
166
}
167
167
}
168
168
169
- // ===== TzProvider APIs for ZonedDateTime =====
169
+ // ===== Experimental TZ_PROVIDER accessor implementations =====
170
170
171
171
#[ cfg( feature = "experimental" ) ]
172
172
impl ZonedDateTime {
@@ -240,7 +240,103 @@ impl ZonedDateTime {
240
240
241
241
self . millisecond_with_provider ( provider. deref ( ) )
242
242
}
243
+ }
244
+
245
+ // ==== Experimental TZ_PROVIDER calendar method implementations ====
246
+
247
+ #[ cfg( feature = "experimental" ) ]
248
+ impl ZonedDateTime {
249
+ pub fn era ( & self ) -> TemporalResult < Option < TinyAsciiStr < 16 > > > {
250
+ let provider = TZ_PROVIDER
251
+ . lock ( )
252
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
253
+ self . era_with_provider ( provider. deref ( ) )
254
+ }
255
+
256
+ pub fn era_year ( & self ) -> TemporalResult < Option < i32 > > {
257
+ let provider = TZ_PROVIDER
258
+ . lock ( )
259
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
260
+ self . era_year_with_provider ( provider. deref ( ) )
261
+ }
262
+
263
+ /// Returns the calendar day of week value.
264
+ pub fn day_of_week ( & self ) -> TemporalResult < u16 > {
265
+ let provider = TZ_PROVIDER
266
+ . lock ( )
267
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
268
+ self . day_of_week_with_provider ( provider. deref ( ) )
269
+ }
270
+
271
+ /// Returns the calendar day of year value.
272
+ pub fn day_of_year ( & self ) -> TemporalResult < u16 > {
273
+ let provider = TZ_PROVIDER
274
+ . lock ( )
275
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
276
+ self . day_of_year_with_provider ( provider. deref ( ) )
277
+ }
278
+
279
+ /// Returns the calendar week of year value.
280
+ pub fn week_of_year ( & self ) -> TemporalResult < Option < u16 > > {
281
+ let provider = TZ_PROVIDER
282
+ . lock ( )
283
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
284
+ self . week_of_year_with_provider ( provider. deref ( ) )
285
+ }
286
+
287
+ /// Returns the calendar year of week value.
288
+ pub fn year_of_week ( & self ) -> TemporalResult < Option < i32 > > {
289
+ let provider = TZ_PROVIDER
290
+ . lock ( )
291
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
292
+ self . year_of_week_with_provider ( provider. deref ( ) )
293
+ }
294
+
295
+ /// Returns the calendar days in week value.
296
+ pub fn days_in_week ( & self ) -> TemporalResult < u16 > {
297
+ let provider = TZ_PROVIDER
298
+ . lock ( )
299
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
300
+ self . days_in_week_with_provider ( provider. deref ( ) )
301
+ }
302
+
303
+ /// Returns the calendar days in month value.
304
+ pub fn days_in_month ( & self ) -> TemporalResult < u16 > {
305
+ let provider = TZ_PROVIDER
306
+ . lock ( )
307
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
308
+ self . days_in_month_with_provider ( provider. deref ( ) )
309
+ }
310
+
311
+ /// Returns the calendar days in year value.
312
+ pub fn days_in_year ( & self ) -> TemporalResult < u16 > {
313
+ let provider = TZ_PROVIDER
314
+ . lock ( )
315
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
316
+ self . days_in_year_with_provider ( provider. deref ( ) )
317
+ }
318
+
319
+ /// Returns the calendar months in year value.
320
+ pub fn months_in_year ( & self ) -> TemporalResult < u16 > {
321
+ let provider = TZ_PROVIDER
322
+ . lock ( )
323
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
324
+ self . months_in_year_with_provider ( provider. deref ( ) )
325
+ }
243
326
327
+ /// Returns returns whether the date in a leap year for the given calendar.
328
+ pub fn in_leap_year ( & self ) -> TemporalResult < bool > {
329
+ let provider = TZ_PROVIDER
330
+ . lock ( )
331
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
332
+ self . in_leap_year_with_provider ( provider. deref ( ) )
333
+ }
334
+ }
335
+
336
+ // ==== Experimental TZ_PROVIDER method implementations ====
337
+
338
+ #[ cfg( feature = "experimental" ) ]
339
+ impl ZonedDateTime {
244
340
pub fn add (
245
341
& self ,
246
342
duration : & Duration ,
@@ -270,9 +366,44 @@ impl ZonedDateTime {
270
366
overflow. unwrap_or ( ArithmeticOverflow :: Constrain ) ,
271
367
provider. deref ( ) ,
272
368
)
369
+
273
370
}
274
371
}
275
372
373
+ // ==== HoursInDay accessor method implementation ====
374
+
375
+ impl ZonedDateTime {
376
+ #[ cfg( feature = "experimental" ) ]
377
+ pub fn hours_in_day ( & self ) -> TemporalResult < u8 > {
378
+ let provider = TZ_PROVIDER
379
+ . lock ( )
380
+ . map_err ( |_| TemporalError :: general ( "Unable to acquire lock" ) ) ?;
381
+ self . hours_in_day_with_provider ( provider. deref ( ) )
382
+ }
383
+
384
+ pub fn hours_in_day_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u8 > {
385
+ // 1-3. Is engine specific steps
386
+ // 4. Let isoDateTime be GetISODateTimeFor(timeZone, zonedDateTime.[[EpochNanoseconds]]).
387
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
388
+ // 5. Let today be isoDateTime.[[ISODate]].
389
+ let today = iso. date ;
390
+ // 6. Let tomorrow be BalanceISODate(today.[[Year]], today.[[Month]], today.[[Day]] + 1).
391
+ let tomorrow = IsoDate :: balance ( today. year , today. month . into ( ) , i32:: from ( today. day + 1 ) ) ;
392
+ // 7. Let todayNs be ? GetStartOfDay(timeZone, today).
393
+ let today_ns = self . tz . get_start_of_day ( & today, provider) ?;
394
+ // 8. Let tomorrowNs be ? GetStartOfDay(timeZone, tomorrow).
395
+ let tomorrow_ns = self . tz . get_start_of_day ( & tomorrow, provider) ?;
396
+ // 9. Let diff be TimeDurationFromEpochNanosecondsDifference(tomorrowNs, todayNs).
397
+ let diff = NormalizedTimeDuration :: from_nanosecond_difference ( tomorrow_ns, today_ns) ?;
398
+ // NOTE: The below should be safe as today_ns and tomorrow_ns should be at most 25 hours.
399
+ // TODO: Tests for the below cast.
400
+ // 10. Return 𝔽(TotalTimeDuration(diff, hour)).
401
+ Ok ( diff. divide ( 60_000_000_000 ) as u8 )
402
+ }
403
+ }
404
+
405
+ // ==== Core accessor methods ====
406
+
276
407
impl ZonedDateTime {
277
408
/// Returns the `year` value for this `ZonedDateTime`.
278
409
#[ inline]
@@ -341,7 +472,98 @@ impl ZonedDateTime {
341
472
let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
342
473
Ok ( iso. time . nanosecond )
343
474
}
475
+ }
476
+
477
+ // ==== Core calendar method implementations ====
478
+
479
+ impl ZonedDateTime {
480
+ pub fn era_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < Option < TinyAsciiStr < 16 > > > {
481
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
482
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
483
+ self . calendar . era ( & CalendarDateLike :: DateTime ( & pdt) )
484
+ }
485
+
486
+ pub fn era_year_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < Option < i32 > > {
487
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
488
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
489
+ self . calendar . era_year ( & CalendarDateLike :: DateTime ( & pdt) )
344
490
491
+ }
492
+
493
+ /// Returns the calendar day of week value.
494
+ pub fn day_of_week_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u16 > {
495
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
496
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
497
+ self . calendar . day_of_week ( & CalendarDateLike :: DateTime ( & pdt) )
498
+
499
+ }
500
+
501
+ /// Returns the calendar day of year value.
502
+ pub fn day_of_year_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u16 > {
503
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
504
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
505
+ self . calendar . day_of_year ( & CalendarDateLike :: DateTime ( & pdt) )
506
+ }
507
+
508
+ /// Returns the calendar week of year value.
509
+ pub fn week_of_year_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < Option < u16 > > {
510
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
511
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
512
+ self . calendar . week_of_year ( & CalendarDateLike :: DateTime ( & pdt) )
513
+
514
+ }
515
+
516
+ /// Returns the calendar year of week value.
517
+ pub fn year_of_week_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < Option < i32 > > {
518
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
519
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
520
+ self . calendar . year_of_week ( & CalendarDateLike :: DateTime ( & pdt) )
521
+
522
+ }
523
+
524
+ /// Returns the calendar days in week value.
525
+ pub fn days_in_week_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u16 > {
526
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
527
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
528
+ self . calendar . days_in_week ( & CalendarDateLike :: DateTime ( & pdt) )
529
+
530
+ }
531
+
532
+ /// Returns the calendar days in month value.
533
+ pub fn days_in_month_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u16 > {
534
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
535
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
536
+ self . calendar . days_in_month ( & CalendarDateLike :: DateTime ( & pdt) )
537
+
538
+ }
539
+
540
+ /// Returns the calendar days in year value.
541
+ pub fn days_in_year_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u16 > {
542
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
543
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
544
+ self . calendar . days_in_year ( & CalendarDateLike :: DateTime ( & pdt) )
545
+ }
546
+
547
+ /// Returns the calendar months in year value.
548
+ pub fn months_in_year_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < u16 > {
549
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
550
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
551
+ self . calendar . months_in_year ( & CalendarDateLike :: DateTime ( & pdt) )
552
+
553
+ }
554
+
555
+ /// Returns returns whether the date in a leap year for the given calendar.
556
+ pub fn in_leap_year_with_provider ( & self , provider : & impl TzProvider ) -> TemporalResult < bool > {
557
+ let iso = self . tz . get_iso_datetime_for ( & self . instant , provider) ?;
558
+ let pdt = PlainDateTime :: new_unchecked ( iso, self . calendar . clone ( ) ) ;
559
+ self . calendar . in_leap_year ( & CalendarDateLike :: DateTime ( & pdt) )
560
+ }
561
+
562
+ }
563
+
564
+ // ==== Core method implementations ====
565
+
566
+ impl ZonedDateTime {
345
567
pub fn add_with_provider (
346
568
& self ,
347
569
duration : & Duration ,
0 commit comments