• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zbraniecki / icu4x / 9357137046

03 Jun 2024 08:51PM UTC coverage: 75.121% (-1.1%) from 76.254%
9357137046

push

github

web-flow
Switch locid Value to use Subtag (#4941)

This is part of #1833 switching Value API to use Subtag.

61 of 71 new or added lines in 11 files covered. (85.92%)

3224 existing lines in 178 files now uncovered.

52958 of 70497 relevant lines covered (75.12%)

572757.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.05
/components/datetime/src/input.rs
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4

5
//! A collection of utilities for representing and working with dates as an input to
6
//! formatting operations.
7

8
#[cfg(feature = "experimental")]
9
use crate::neo_marker::{DateMarkers, NeoGetField, TimeMarkers, TypedDateMarkers};
10
use crate::provider::time_zones::{MetazoneId, TimeZoneBcp47Id};
11
use icu_calendar::any_calendar::AnyCalendarKind;
12
use icu_calendar::week::{RelativeUnit, WeekCalculator};
13
use icu_calendar::Calendar;
14
use icu_calendar::{AsCalendar, Date, DateTime, Iso};
15
use icu_timezone::{CustomTimeZone, GmtOffset, ZoneVariant};
16

17
// TODO(#2630) fix up imports to directly import from icu_calendar
18
pub(crate) use icu_calendar::types::{
19
    DayOfMonth, DayOfWeekInMonth, DayOfYearInfo, FormattableMonth, FormattableYear, IsoHour,
20
    IsoMinute, IsoSecond, IsoWeekday, NanoSecond, Time, WeekOfMonth, WeekOfYear,
21
};
22
pub(crate) use icu_calendar::CalendarError;
23

24
/// Representation of a formattable calendar date. Supports dates in any calendar system that uses
25
/// solar days indexed by an era, year, month, and day.
26
///
27
/// All fields are optional. If a field is not present but is required when formatting, an error
28
/// result will be returned from the formatter.
29
///
30
/// All data represented in [`DateInput`] should be locale-agnostic.
31
pub trait DateInput {
32
    /// The calendar this date relates to
33
    type Calendar: Calendar;
34
    /// Gets the era and year input.
35
    fn year(&self) -> Option<FormattableYear>;
36

37
    /// Gets the month input.
38
    fn month(&self) -> Option<FormattableMonth>;
39

40
    /// Gets the day input.
41
    fn day_of_month(&self) -> Option<DayOfMonth>;
42

43
    /// Gets the weekday input.
44
    fn iso_weekday(&self) -> Option<IsoWeekday>;
45

46
    /// Gets information on the position of the day within the year.
47
    fn day_of_year_info(&self) -> Option<DayOfYearInfo>;
48

49
    /// Gets the kind of calendar this date is for, if associated with [`AnyCalendar`]
50
    /// In most cases you'll probably want to return [`AnyCalendarKind::Iso`].
51
    ///
52
    /// [`AnyCalendar`]: icu_calendar::any_calendar::AnyCalendar
53
    fn any_calendar_kind(&self) -> Option<AnyCalendarKind>;
54

55
    /// Converts date to ISO
56
    fn to_iso(&self) -> Date<Iso>;
57
}
58

59
/// Representation of a time of day according to ISO-8601 conventions. Always indexed from
60
/// midnight, regardless of calendar system.
61
///
62
/// All fields are optional. If a field is not present but is required when formatting, an error
63
/// result will be returned from the formatter.
64
///
65
/// All data represented in [`IsoTimeInput`] should be locale-agnostic.
66
pub trait IsoTimeInput {
67
    /// Gets the hour input.
68
    fn hour(&self) -> Option<IsoHour>;
69

70
    /// Gets the minute input.
71
    fn minute(&self) -> Option<IsoMinute>;
72

73
    /// Gets the second input.
74
    fn second(&self) -> Option<IsoSecond>;
75

76
    /// Gets the nanosecond input.
77
    fn nanosecond(&self) -> Option<NanoSecond>;
78
}
79

80
/// Representation of a formattable time zone.
81
///
82
/// Only the [`GmtOffset`] is required, since it is the final format fallback.
83
///
84
/// All data represented in [`TimeZoneInput`] should be locale-agnostic.
85
pub trait TimeZoneInput {
86
    /// The GMT offset in Nanoseconds.
87
    fn gmt_offset(&self) -> Option<GmtOffset>;
88

89
    /// The IANA time-zone identifier.
90
    fn time_zone_id(&self) -> Option<TimeZoneBcp47Id>;
91

92
    /// The metazone identifier.
93
    fn metazone_id(&self) -> Option<MetazoneId>;
94

95
    /// The time variant (e.g. "daylight", "standard")
96
    fn zone_variant(&self) -> Option<ZoneVariant>;
97
}
98

99
/// A combination of a formattable calendar date and ISO time.
100
///
101
/// # Examples
102
///
103
/// If the trait does not return all required fields, an error output will occur:
104
///
105
/// ```
106
/// use icu::calendar::*;
107
/// use icu::calendar::types::*;
108
/// use icu::datetime::input::*;
109
/// use icu::datetime::{DateTimeWriteError, TypedDateTimeNames};
110
/// use icu::datetime::fields::{Field, FieldLength, FieldSymbol, Weekday};
111
/// use icu::datetime::neo_pattern::DateTimePattern;
112
/// use icu::locale::locale;
113
/// use writeable::assert_try_writeable_eq;
114
///
115
/// struct Empty;
116
///
117
/// impl DateInput for Empty {
118
///     type Calendar = Gregorian;
119
///     fn year(&self) -> Option<FormattableYear> { None }
120
///     fn month(&self) -> Option<FormattableMonth> { None }
121
///     fn day_of_month(&self) -> Option<DayOfMonth> { None }
122
///     fn iso_weekday(&self) -> Option<IsoWeekday> { None }
123
///     fn day_of_year_info(&self) -> Option<DayOfYearInfo> { None }
124
///     fn any_calendar_kind(&self) -> Option<AnyCalendarKind> { None }
125
///     fn to_iso(&self) -> icu::calendar::Date<Iso> { todo!() }
126
/// }
127
///
128
/// impl IsoTimeInput for Empty {
129
///     fn hour(&self) -> Option<IsoHour> { None }
130
///     fn minute(&self) -> Option<IsoMinute> { None }
131
///     fn second(&self) -> Option<IsoSecond> { None }
132
///     fn nanosecond(&self) -> Option<NanoSecond> { None }
133
/// }
134
///
135
/// // Create an instance that can format abbreviated month, weekday, and day period names:
136
/// let mut names: TypedDateTimeNames<Gregorian> =
137
///     TypedDateTimeNames::try_new(&locale!("en").into()).unwrap();
138
///
139
/// // Create a pattern from a pattern string:
140
/// let pattern_str = "'It is:' E MMM d y G 'at' h:mm:ssSSS a";
141
/// let pattern: DateTimePattern = pattern_str.parse().unwrap();
142
///
143
/// // The pattern string contains lots of symbols, but our DateTimeInput is empty!
144
/// let mut buffer = String::new();
145
/// // Missing data is filled in on a best-effort basis, and an error is signaled.
146
/// assert_try_writeable_eq!(
147
///     names.with_pattern(&pattern).format(&Empty),
148
///     "It is: {E} {M} {d} {y} {G} at {h}:{m}:{s}{S} {a}",
149
///     Err(DateTimeWriteError::MissingInputField("iso_weekday"))
150
/// );
151
/// ```
152
pub trait DateTimeInput: DateInput + IsoTimeInput {}
153

154
impl<T> DateTimeInput for T where T: DateInput + IsoTimeInput {}
155

156
/// A formattable calendar date and ISO time that takes the locale into account.
157
#[deprecated(since = "1.5.0", note = "not used in any ICU4X APIs")]
158
pub trait LocalizedDateTimeInput<T: DateTimeInput> {
159
    /// A reference to this instance's [`DateTimeInput`].
160
    fn datetime(&self) -> &T;
161

162
    /// The week of the month.
163
    ///
164
    /// For example, January 1, 2021 is part of the first week of January.
165
    fn week_of_month(&self) -> Result<WeekOfMonth, CalendarError>;
166

167
    /// The week number of the year and the corresponding year.
168
    ///
169
    /// For example, December 31, 2020 is part of the first week of 2021.
170
    fn week_of_year(&self) -> Result<(FormattableYear, WeekOfYear), CalendarError>;
171

172
    /// The day of week in this month.
173
    ///
174
    /// For example, July 8, 2020 is the 2nd Wednesday of July.
175
    fn day_of_week_in_month(&self) -> Result<DayOfWeekInMonth, CalendarError>;
176

177
    /// TODO(#487): Implement flexible day periods.
178
    fn flexible_day_period(&self);
179
}
180

181
/// A [`DateTimeInput`] type with all of the fields pre-extracted
182
///
183
/// See [`DateTimeInput`] for documentation on individual fields
184
#[derive(Default, Debug, Copy, Clone)]
4✔
185
pub(crate) struct ExtractedDateTimeInput {
186
    year: Option<FormattableYear>,
2✔
187
    month: Option<FormattableMonth>,
2✔
188
    day_of_month: Option<DayOfMonth>,
2✔
189
    iso_weekday: Option<IsoWeekday>,
2✔
190
    day_of_year_info: Option<DayOfYearInfo>,
2✔
191
    any_calendar_kind: Option<AnyCalendarKind>,
2✔
192
    hour: Option<IsoHour>,
2✔
193
    minute: Option<IsoMinute>,
2✔
194
    second: Option<IsoSecond>,
2✔
195
    nanosecond: Option<NanoSecond>,
2✔
196
}
197

198
/// A [`TimeZoneInput`] type with all of the fields pre-extracted
199
///
200
/// See [`TimeZoneInput`] for documentation on individual fields
201
#[derive(Debug, Copy, Clone)]
×
202
pub(crate) struct ExtractedTimeZoneInput {
203
    gmt_offset: Option<GmtOffset>,
204
    time_zone_id: Option<TimeZoneBcp47Id>,
×
205
    metazone_id: Option<MetazoneId>,
×
206
    zone_variant: Option<ZoneVariant>,
×
207
}
208

209
impl ExtractedDateTimeInput {
210
    /// Construct given an instance of a [`DateTimeInput`].
211
    pub(crate) fn extract_from<T: DateTimeInput>(input: &T) -> Self {
47✔
212
        Self {
47✔
213
            year: input.year(),
47✔
214
            month: input.month(),
47✔
215
            day_of_month: input.day_of_month(),
47✔
216
            iso_weekday: input.iso_weekday(),
47✔
217
            day_of_year_info: input.day_of_year_info(),
47✔
218
            any_calendar_kind: input.any_calendar_kind(),
47✔
219
            hour: input.hour(),
47✔
220
            minute: input.minute(),
47✔
221
            second: input.second(),
47✔
222
            nanosecond: input.nanosecond(),
47✔
223
        }
224
    }
47✔
225
    /// Construct given an instance of a [`DateTimeInput`].
226
    pub(crate) fn extract_from_date<T: DateInput>(input: &T) -> Self {
2✔
227
        Self {
2✔
228
            year: input.year(),
2✔
229
            month: input.month(),
2✔
230
            day_of_month: input.day_of_month(),
2✔
231
            iso_weekday: input.iso_weekday(),
2✔
232
            day_of_year_info: input.day_of_year_info(),
2✔
233
            any_calendar_kind: input.any_calendar_kind(),
2✔
234
            ..Default::default()
2✔
235
        }
236
    }
2✔
237
    /// Construct given an instance of a [`DateTimeInput`].
238
    pub(crate) fn extract_from_time<T: IsoTimeInput>(input: &T) -> Self {
×
239
        Self {
×
240
            hour: input.hour(),
×
241
            minute: input.minute(),
×
242
            second: input.second(),
×
243
            nanosecond: input.nanosecond(),
×
244
            ..Default::default()
×
245
        }
246
    }
×
247
    /// Construct given neo date input instances.
248
    #[cfg(feature = "experimental")]
249
    pub(crate) fn extract_from_typed_neo_input<C, D, T, I>(input: &I) -> Self
250
    where
251
        D: TypedDateMarkers<C>,
252
        T: TimeMarkers,
253
        I: ?Sized
254
            + NeoGetField<D::YearInput>
255
            + NeoGetField<D::MonthInput>
256
            + NeoGetField<D::DayOfMonthInput>
257
            + NeoGetField<D::DayOfWeekInput>
258
            + NeoGetField<D::DayOfYearInput>
259
            + NeoGetField<D::AnyCalendarKindInput>
260
            + NeoGetField<T::HourInput>
261
            + NeoGetField<T::MinuteInput>
262
            + NeoGetField<T::SecondInput>
263
            + NeoGetField<T::NanoSecondInput>,
264
    {
265
        Self {
266
            year: NeoGetField::<D::YearInput>::get_field(input).into(),
267
            month: NeoGetField::<D::MonthInput>::get_field(input).into(),
268
            day_of_month: NeoGetField::<D::DayOfMonthInput>::get_field(input).into(),
269
            iso_weekday: NeoGetField::<D::DayOfWeekInput>::get_field(input).into(),
270
            day_of_year_info: NeoGetField::<D::DayOfYearInput>::get_field(input).into(),
271
            any_calendar_kind: NeoGetField::<D::AnyCalendarKindInput>::get_field(input).into(),
272
            hour: NeoGetField::<T::HourInput>::get_field(input).into(),
273
            minute: NeoGetField::<T::MinuteInput>::get_field(input).into(),
274
            second: NeoGetField::<T::SecondInput>::get_field(input).into(),
275
            nanosecond: NeoGetField::<T::NanoSecondInput>::get_field(input).into(),
276
        }
277
    }
278
    /// Construct given neo date input instances.
279
    #[cfg(feature = "experimental")]
280
    pub(crate) fn extract_from_any_neo_input<D, T, I>(input: &I) -> Self
281
    where
282
        D: DateMarkers,
283
        T: TimeMarkers,
284
        I: ?Sized
285
            + NeoGetField<D::YearInput>
286
            + NeoGetField<D::MonthInput>
287
            + NeoGetField<D::DayOfMonthInput>
288
            + NeoGetField<D::DayOfWeekInput>
289
            + NeoGetField<D::DayOfYearInput>
290
            + NeoGetField<D::AnyCalendarKindInput>
291
            + NeoGetField<T::HourInput>
292
            + NeoGetField<T::MinuteInput>
293
            + NeoGetField<T::SecondInput>
294
            + NeoGetField<T::NanoSecondInput>,
295
    {
296
        Self {
297
            year: NeoGetField::<D::YearInput>::get_field(input).into(),
298
            month: NeoGetField::<D::MonthInput>::get_field(input).into(),
299
            day_of_month: NeoGetField::<D::DayOfMonthInput>::get_field(input).into(),
300
            iso_weekday: NeoGetField::<D::DayOfWeekInput>::get_field(input).into(),
301
            day_of_year_info: NeoGetField::<D::DayOfYearInput>::get_field(input).into(),
302
            any_calendar_kind: NeoGetField::<D::AnyCalendarKindInput>::get_field(input).into(),
303
            hour: NeoGetField::<T::HourInput>::get_field(input).into(),
304
            minute: NeoGetField::<T::MinuteInput>::get_field(input).into(),
305
            second: NeoGetField::<T::SecondInput>::get_field(input).into(),
306
            nanosecond: NeoGetField::<T::NanoSecondInput>::get_field(input).into(),
307
        }
308
    }
309
}
310

311
impl ExtractedTimeZoneInput {
312
    /// Construct given an instance of a [`ZonedDateTimeInput`].
313
    pub(crate) fn extract_from<T: TimeZoneInput>(input: &T) -> Self {
1✔
314
        Self {
1✔
315
            gmt_offset: input.gmt_offset(),
1✔
316
            time_zone_id: input.time_zone_id(),
1✔
317
            metazone_id: input.metazone_id(),
1✔
318
            zone_variant: input.zone_variant(),
1✔
319
        }
320
    }
1✔
321
}
322

323
impl DateInput for ExtractedDateTimeInput {
324
    /// This actually doesn't matter, by the time we use this
325
    /// it's purely internal raw code where calendars are irrelevant
326
    type Calendar = icu_calendar::any_calendar::AnyCalendar;
327
    fn year(&self) -> Option<FormattableYear> {
5,009✔
328
        self.year
5,009✔
329
    }
5,009✔
330
    fn month(&self) -> Option<FormattableMonth> {
2,878✔
331
        self.month
2,878✔
332
    }
2,878✔
333
    fn day_of_month(&self) -> Option<DayOfMonth> {
2,778✔
334
        self.day_of_month
2,778✔
335
    }
2,778✔
336
    fn iso_weekday(&self) -> Option<IsoWeekday> {
1,831✔
337
        self.iso_weekday
1,831✔
338
    }
1,831✔
339
    fn day_of_year_info(&self) -> Option<DayOfYearInfo> {
505✔
340
        self.day_of_year_info
505✔
341
    }
505✔
342
    fn any_calendar_kind(&self) -> Option<AnyCalendarKind> {
167✔
343
        self.any_calendar_kind
167✔
344
    }
167✔
UNCOV
345
    fn to_iso(&self) -> Date<Iso> {
×
UNCOV
346
        unreachable!("ExtractedDateTimeInput should never be directly passed to DateTimeFormatter")
×
347
    }
348
}
349

350
impl IsoTimeInput for ExtractedDateTimeInput {
351
    fn hour(&self) -> Option<IsoHour> {
4,437✔
352
        self.hour
4,437✔
353
    }
4,437✔
354
    fn minute(&self) -> Option<IsoMinute> {
4,283✔
355
        self.minute
4,283✔
356
    }
4,283✔
357
    fn second(&self) -> Option<IsoSecond> {
3,467✔
358
        self.second
3,467✔
359
    }
3,467✔
360
    fn nanosecond(&self) -> Option<NanoSecond> {
1,919✔
361
        self.nanosecond
1,919✔
362
    }
1,919✔
363
}
364

365
impl TimeZoneInput for ExtractedTimeZoneInput {
366
    fn gmt_offset(&self) -> Option<GmtOffset> {
625✔
367
        self.gmt_offset
625✔
368
    }
625✔
369
    fn time_zone_id(&self) -> Option<TimeZoneBcp47Id> {
325✔
370
        self.time_zone_id
325✔
371
    }
325✔
372
    fn metazone_id(&self) -> Option<MetazoneId> {
277✔
373
        self.metazone_id
277✔
374
    }
277✔
375
    fn zone_variant(&self) -> Option<ZoneVariant> {
246✔
376
        self.zone_variant
246✔
377
    }
246✔
378
}
379

380
pub(crate) enum ExtractedDateTimeInputWeekCalculatorError {
381
    Missing(&'static str),
382
}
383

384
impl ExtractedDateTimeInput {
385
    pub(crate) fn week_of_month(
36✔
386
        &self,
387
        calculator: &WeekCalculator,
388
    ) -> Result<WeekOfMonth, ExtractedDateTimeInputWeekCalculatorError> {
389
        let day_of_month =
390
            self.day_of_month()
72✔
391
                .ok_or(ExtractedDateTimeInputWeekCalculatorError::Missing(
36✔
392
                    "day_of_month",
UNCOV
393
                ))?;
×
394
        let iso_weekday =
395
            self.iso_weekday()
72✔
396
                .ok_or(ExtractedDateTimeInputWeekCalculatorError::Missing(
36✔
397
                    "iso_weekday",
UNCOV
398
                ))?;
×
399
        Ok(calculator.week_of_month(day_of_month, iso_weekday))
36✔
400
    }
36✔
401

402
    pub(crate) fn week_of_year(
500✔
403
        &self,
404
        calculator: &WeekCalculator,
405
    ) -> Result<(FormattableYear, WeekOfYear), ExtractedDateTimeInputWeekCalculatorError> {
406
        let day_of_year_info =
407
            self.day_of_year_info()
1,000✔
408
                .ok_or(ExtractedDateTimeInputWeekCalculatorError::Missing(
500✔
409
                    "day_of_year_info",
UNCOV
410
                ))?;
×
411
        let iso_weekday =
412
            self.iso_weekday()
1,000✔
413
                .ok_or(ExtractedDateTimeInputWeekCalculatorError::Missing(
500✔
414
                    "iso_weekday",
UNCOV
415
                ))?;
×
416
        // We don't have any calendars with < 14 days per year, and it's unlikely we'll add one
417
        debug_assert!(day_of_year_info.day_of_year >= icu_calendar::week::MIN_UNIT_DAYS);
500✔
418
        debug_assert!(day_of_year_info.days_in_prev_year >= icu_calendar::week::MIN_UNIT_DAYS);
500✔
419
        #[allow(clippy::unwrap_used)]
420
        let week_of = calculator
500✔
421
            .week_of_year(day_of_year_info, iso_weekday)
422
            .unwrap();
423
        let year = match week_of.unit {
500✔
UNCOV
424
            RelativeUnit::Previous => day_of_year_info.prev_year,
×
425
            RelativeUnit::Current => self
1,000✔
426
                .year()
427
                .ok_or(ExtractedDateTimeInputWeekCalculatorError::Missing("year"))?,
500✔
UNCOV
428
            RelativeUnit::Next => day_of_year_info.next_year,
×
429
        };
430
        Ok((year, WeekOfYear(week_of.week as u32)))
500✔
431
    }
500✔
432
}
433

434
impl<C: Calendar, A: AsCalendar<Calendar = C>> DateInput for Date<A> {
435
    type Calendar = C;
436
    /// Gets the era and year input.
437
    fn year(&self) -> Option<FormattableYear> {
2✔
438
        Some(self.year())
2✔
439
    }
2✔
440

441
    /// Gets the month input.
442
    fn month(&self) -> Option<FormattableMonth> {
2✔
443
        Some(self.month())
2✔
444
    }
2✔
445

446
    /// Gets the day input.
447
    fn day_of_month(&self) -> Option<DayOfMonth> {
2✔
448
        Some(self.day_of_month())
2✔
449
    }
2✔
450

451
    /// Gets the weekday input.
452
    fn iso_weekday(&self) -> Option<IsoWeekday> {
2✔
453
        Some(self.day_of_week())
2✔
454
    }
2✔
455

456
    /// Gets information on the position of the day within the year.
457
    fn day_of_year_info(&self) -> Option<DayOfYearInfo> {
2✔
458
        Some(self.day_of_year_info())
2✔
459
    }
2✔
460

461
    fn any_calendar_kind(&self) -> Option<AnyCalendarKind> {
4✔
462
        self.calendar().any_calendar_kind()
4✔
463
    }
4✔
464

465
    fn to_iso(&self) -> Date<Iso> {
1✔
466
        Date::to_iso(self)
1✔
467
    }
1✔
468
}
469

470
impl<C: Calendar, A: AsCalendar<Calendar = C>> DateInput for DateTime<A> {
471
    type Calendar = C;
472
    /// Gets the era and year input.
473
    fn year(&self) -> Option<FormattableYear> {
46✔
474
        Some(self.date.year())
46✔
475
    }
46✔
476

477
    /// Gets the month input.
478
    fn month(&self) -> Option<FormattableMonth> {
46✔
479
        Some(self.date.month())
46✔
480
    }
46✔
481

482
    /// Gets the day input.
483
    fn day_of_month(&self) -> Option<DayOfMonth> {
46✔
484
        Some(self.date.day_of_month())
46✔
485
    }
46✔
486

487
    /// Gets the weekday input.
488
    fn iso_weekday(&self) -> Option<IsoWeekday> {
46✔
489
        Some(self.date.day_of_week())
46✔
490
    }
46✔
491

492
    /// Gets information on the position of the day within the year.
493
    fn day_of_year_info(&self) -> Option<DayOfYearInfo> {
46✔
494
        Some(self.date.day_of_year_info())
46✔
495
    }
46✔
496

497
    fn any_calendar_kind(&self) -> Option<AnyCalendarKind> {
54✔
498
        self.date.calendar().any_calendar_kind()
54✔
499
    }
54✔
500
    fn to_iso(&self) -> Date<Iso> {
8✔
501
        Date::to_iso(&self.date)
8✔
502
    }
8✔
503
}
504

505
impl<A: AsCalendar> IsoTimeInput for DateTime<A> {
506
    /// Gets the hour input.
507
    fn hour(&self) -> Option<IsoHour> {
54✔
508
        Some(self.time.hour)
54✔
509
    }
54✔
510

511
    /// Gets the minute input.
512
    fn minute(&self) -> Option<IsoMinute> {
54✔
513
        Some(self.time.minute)
54✔
514
    }
54✔
515

516
    /// Gets the second input.
517
    fn second(&self) -> Option<IsoSecond> {
54✔
518
        Some(self.time.second)
54✔
519
    }
54✔
520

521
    /// Gets the fractional second input.
522
    fn nanosecond(&self) -> Option<NanoSecond> {
54✔
523
        Some(self.time.nanosecond)
54✔
524
    }
54✔
525
}
526

527
impl TimeZoneInput for CustomTimeZone {
528
    fn gmt_offset(&self) -> Option<GmtOffset> {
435✔
529
        self.gmt_offset
435✔
530
    }
435✔
531

532
    fn time_zone_id(&self) -> Option<TimeZoneBcp47Id> {
358✔
533
        self.time_zone_id
358✔
534
    }
358✔
535

536
    fn metazone_id(&self) -> Option<MetazoneId> {
296✔
537
        self.metazone_id
296✔
538
    }
296✔
539

540
    fn zone_variant(&self) -> Option<ZoneVariant> {
266✔
541
        self.zone_variant
266✔
542
    }
266✔
543
}
544

545
impl IsoTimeInput for Time {
546
    fn hour(&self) -> Option<IsoHour> {
5✔
547
        Some(self.hour)
5✔
548
    }
5✔
549
    fn minute(&self) -> Option<IsoMinute> {
5✔
550
        Some(self.minute)
5✔
551
    }
5✔
552
    fn second(&self) -> Option<IsoSecond> {
5✔
553
        Some(self.second)
5✔
554
    }
5✔
555
    fn nanosecond(&self) -> Option<NanoSecond> {
5✔
556
        Some(self.nanosecond)
5✔
557
    }
5✔
558
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc