Skip to main content

time/format_description/
modifier.rs

1//! Various modifiers for components.
2
3use core::num::NonZero;
4
5/// Generate the provided code if and only if `pub` is present.
6macro_rules! if_pub {
7    (pub $(#[$attr:meta])*; $($x:tt)*) => {
8        $(#[$attr])*
9        ///
10        /// This function exists since [`Default::default()`] cannot be used in a `const` context.
11        /// It may be removed once that becomes possible. As the [`Default`] trait is in the
12        /// prelude, removing this function in the future will not cause any resolution failures for
13        /// the overwhelming majority of users; only users who use `#![no_implicit_prelude]` will be
14        /// affected. As such it will not be considered a breaking change.
15        $($x)*
16    };
17    ($($_:tt)*) => {};
18}
19
20/// Implement `Default` for the given type. This also generates an inherent implementation of a
21/// `default` method that is `const fn`, permitting the default value to be used in const contexts.
22// Every modifier should use this macro rather than a derived `Default`.
23macro_rules! impl_const_default {
24    ($($(
25        #[doc = $doc:expr])*
26        $(#[cfg($($cfg:tt)+)])?
27        $(#[expect($($expected:tt)+)])?
28        $(@$pub:ident)? $type:ty => $default:expr;
29    )*) => {$(
30        $(#[cfg($($cfg)+)])?
31        $(#[expect($($expected)+)])?
32        impl $type {
33            if_pub! {
34                $($pub)?
35                $(#[doc = $doc])*;
36                #[inline]
37                pub const fn default() -> Self {
38                    $default
39                }
40            }
41        }
42
43        $(#[doc = $doc])*
44        $(#[cfg($($cfg)+)])?
45        $(#[expect($($expected)+)])?
46        impl Default for $type {
47            #[inline]
48            fn default() -> Self {
49                $default
50            }
51        }
52    )*};
53}
54
55// Keep this first so that it's shown at the top of documentation.
56impl_const_default! {
57    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero).
58    @pub Day => Self { padding: Padding::Zero };
59    /// Creates a modifier that indicates the value uses the
60    /// [`Numerical`](Self::Numerical) representation.
61    #[expect(deprecated)]
62    MonthRepr => Self::Numerical;
63    @pub MonthShort => Self { case_sensitive: true };
64    @pub MonthLong => Self { case_sensitive: true };
65    @pub MonthNumerical => Self { padding: Padding::Zero };
66    /// Creates an instance of this type that indicates the value uses the
67    /// [`Numerical`](MonthRepr::Numerical) representation, is [padded with zeroes](Padding::Zero),
68    /// and is case-sensitive when parsing.
69    #[expect(deprecated)]
70    @pub Month => Self {
71        padding: Padding::Zero,
72        repr: MonthRepr::Numerical,
73        case_sensitive: true,
74    };
75    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero).
76    @pub Ordinal => Self { padding: Padding::Zero };
77    /// Creates a modifier that indicates the value uses the [`Long`](Self::Long) representation.
78    #[expect(deprecated)]
79    WeekdayRepr => Self::Long;
80    @pub WeekdayShort => Self { case_sensitive: true };
81    @pub WeekdayLong => Self { case_sensitive: true };
82    @pub WeekdaySunday => Self { one_indexed: true };
83    @pub WeekdayMonday => Self { one_indexed: true };
84    /// Creates a modifier that indicates the value uses the [`Long`](WeekdayRepr::Long)
85    /// representation and is case-sensitive when parsing. If the representation is changed to a
86    /// numerical one, the instance defaults to one-based indexing.
87    #[expect(deprecated)]
88    @pub Weekday => Self {
89        repr: WeekdayRepr::Long,
90        one_indexed: true,
91        case_sensitive: true,
92    };
93    /// Creates a modifier that indicates that the value uses the [`Iso`](Self::Iso) representation.
94    #[expect(deprecated)]
95    WeekNumberRepr => Self::Iso;
96    @pub WeekNumberIso => Self { padding: Padding::Zero };
97    @pub WeekNumberSunday => Self { padding: Padding::Zero };
98    @pub WeekNumberMonday => Self { padding: Padding::Zero };
99    /// Creates a modifier that indicates that the value is [padded with zeroes](Padding::Zero)
100    /// and uses the [`Iso`](WeekNumberRepr::Iso) representation.
101    #[expect(deprecated)]
102    @pub WeekNumber => Self {
103        padding: Padding::Zero,
104        repr: WeekNumberRepr::Iso,
105    };
106    /// Creates a modifier that indicates the value uses the [`Full`](Self::Full) representation.
107    #[expect(deprecated)]
108    YearRepr => Self::Full;
109    /// Creates a modifier that indicates the value uses the [`Extended`](Self::Extended) range.
110    #[expect(deprecated)]
111    YearRange => Self::Extended;
112    @pub CalendarYearFullExtendedRange => Self {
113        padding: Padding::Zero,
114        sign_is_mandatory: false,
115    };
116    @pub CalendarYearFullStandardRange => Self {
117        padding: Padding::Zero,
118        sign_is_mandatory: false,
119    };
120    @pub IsoYearFullExtendedRange => Self {
121        padding: Padding::Zero,
122        sign_is_mandatory: false,
123    };
124    @pub IsoYearFullStandardRange => Self {
125        padding: Padding::Zero,
126        sign_is_mandatory: false,
127    };
128    @pub CalendarYearCenturyExtendedRange => Self {
129        padding: Padding::Zero,
130        sign_is_mandatory: false,
131    };
132    @pub CalendarYearCenturyStandardRange => Self {
133        padding: Padding::Zero,
134        sign_is_mandatory: false,
135    };
136    @pub IsoYearCenturyExtendedRange => Self {
137        padding: Padding::Zero,
138        sign_is_mandatory: false,
139    };
140    @pub IsoYearCenturyStandardRange => Self {
141        padding: Padding::Zero,
142        sign_is_mandatory: false,
143    };
144    @pub CalendarYearLastTwo => Self {
145        padding: Padding::Zero,
146    };
147    @pub IsoYearLastTwo => Self {
148        padding: Padding::Zero,
149    };
150    /// Creates a modifier that indicates the value uses the [`Full`](YearRepr::Full)
151    /// representation, is [padded with zeroes](Padding::Zero), uses the Gregorian calendar as its
152    /// base, and only includes the year's sign if necessary.
153    #[expect(deprecated)]
154    @pub Year => Self {
155        padding: Padding::Zero,
156        repr: YearRepr::Full,
157        range: YearRange::Extended,
158        iso_week_based: false,
159        sign_is_mandatory: false,
160    };
161    @pub Hour12 => Self { padding: Padding::Zero };
162    @pub Hour24 => Self { padding: Padding::Zero };
163    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero) and
164    /// has the 24-hour representation.
165    #[expect(deprecated)]
166    @pub Hour => Self {
167        padding: Padding::Zero,
168        is_12_hour_clock: false,
169    };
170    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero).
171    @pub Minute => Self { padding: Padding::Zero };
172    /// Creates a modifier that indicates the value uses the upper-case representation and is
173    /// case-sensitive when parsing.
174    @pub Period => Self {
175        is_uppercase: true,
176        case_sensitive: true,
177    };
178    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero).
179    @pub Second => Self { padding: Padding::Zero };
180    /// Creates a modifier that indicates the stringified value contains [one or more
181    /// digits](Self::OneOrMore).
182    SubsecondDigits => Self::OneOrMore;
183    /// Creates a modifier that indicates the stringified value contains [one or more
184    /// digits](SubsecondDigits::OneOrMore).
185    @pub Subsecond => Self { digits: SubsecondDigits::OneOrMore };
186    /// Creates a modifier that indicates the value only uses a sign for negative values and is
187    /// [padded with zeroes](Padding::Zero).
188    @pub OffsetHour => Self {
189        sign_is_mandatory: false,
190        padding: Padding::Zero,
191    };
192    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero).
193    @pub OffsetMinute => Self { padding: Padding::Zero };
194    /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero).
195    @pub OffsetSecond => Self { padding: Padding::Zero };
196    /// Creates a modifier that indicates the value is [padded with zeroes](Self::Zero).
197    Padding => Self::Zero;
198    /// Creates a modifier that indicates the value represents the [number of seconds](Self::Second)
199    /// since the Unix epoch.
200    #[expect(deprecated)]
201    UnixTimestampPrecision => Self::Second;
202    @pub UnixTimestampSecond => Self { sign_is_mandatory: false };
203    @pub UnixTimestampMillisecond => Self { sign_is_mandatory: false };
204    @pub UnixTimestampMicrosecond => Self { sign_is_mandatory: false };
205    @pub UnixTimestampNanosecond => Self { sign_is_mandatory: false };
206    /// Creates a modifier that indicates the value represents the [number of
207    /// seconds](UnixTimestampPrecision::Second) since the Unix epoch. The sign is not mandatory.
208    #[expect(deprecated)]
209    @pub UnixTimestamp => Self {
210        precision: UnixTimestampPrecision::Second,
211        sign_is_mandatory: false,
212    };
213    /// Indicate that any trailing characters after the end of input are prohibited and will cause
214    /// an error when used with `parse`.
215    TrailingInput => Self::Prohibit;
216    /// Creates a modifier used to represent the end of input, not allowing any trailing input (i.e.
217    /// the input must be fully consumed).
218    @pub End => Self { trailing_input: TrailingInput::Prohibit };
219}
220
221macro_rules! builder_methods {
222    ($(
223        $(#[$fn_attr:meta])*
224        fn $method:ident($field:ident : $field_ty:ty);
225    )+) => {$(
226        $(#[$fn_attr])*
227        #[allow(clippy::needless_update, reason = "needed for types with multiple fields")]
228        #[inline]
229        #[must_use = "this returns the result of the operation, without modifying the original"]
230        pub const fn $method(self, $field: $field_ty) -> Self {
231            Self { $field, ..self }
232        }
233    )+ };
234}
235
236/// Day of the month.
237#[non_exhaustive]
238#[derive(Debug, Clone, Copy, PartialEq, Eq)]
239pub struct Day {
240    /// The padding to obtain the minimum width.
241    pub padding: Padding,
242}
243
244impl Day {
245    builder_methods! {
246        /// Set the padding type.
247        fn with_padding(padding: Padding);
248    }
249}
250
251/// The representation of a month.
252#[non_exhaustive]
253#[deprecated(
254    since = "0.3.48",
255    note = "used only in the deprecated `Month` component"
256)]
257#[derive(Debug, Clone, Copy, PartialEq, Eq)]
258pub enum MonthRepr {
259    /// The number of the month (January is 1, December is 12).
260    Numerical,
261    /// The long form of the month name (e.g. "January").
262    Long,
263    /// The short form of the month name (e.g. "Jan").
264    Short,
265}
266
267/// Month of the year using the short form of the month name (e.g. "Jan").
268#[derive(Debug, Clone, Copy, PartialEq, Eq)]
269pub struct MonthShort {
270    /// Is the value case sensitive when parsing?
271    pub(crate) case_sensitive: bool,
272}
273
274impl MonthShort {
275    builder_methods! {
276        /// Set whether the value is case sensitive when parsing.
277        fn with_case_sensitive(case_sensitive: bool);
278    }
279}
280
281/// Month of the year using the long form of the month name (e.g. "January").
282#[derive(Debug, Clone, Copy, PartialEq, Eq)]
283pub struct MonthLong {
284    /// Is the value case sensitive when parsing?
285    pub(crate) case_sensitive: bool,
286}
287
288impl MonthLong {
289    builder_methods! {
290        /// Set whether the value is case sensitive when parsing.
291        fn with_case_sensitive(case_sensitive: bool);
292    }
293}
294
295/// Month of the year using a numerical representation (e.g. "1" for January).
296#[derive(Debug, Clone, Copy, PartialEq, Eq)]
297pub struct MonthNumerical {
298    /// The padding to obtain the minimum width.
299    pub(crate) padding: Padding,
300}
301
302impl MonthNumerical {
303    builder_methods! {
304        /// Set the padding type.
305        fn with_padding(padding: Padding);
306    }
307}
308
309/// Month of the year.
310#[non_exhaustive]
311#[allow(deprecated)]
312#[deprecated(
313    since = "0.3.48",
314    note = "use `MonthShort`, `MonthLong`, or `MonthNumeric` instead"
315)]
316#[derive(Debug, Clone, Copy, PartialEq, Eq)]
317pub struct Month {
318    /// The padding to obtain the minimum width.
319    pub padding: Padding,
320    /// What form of representation should be used?
321    pub repr: MonthRepr,
322    /// Is the value case sensitive when parsing?
323    pub case_sensitive: bool,
324}
325
326#[expect(deprecated)]
327impl Month {
328    builder_methods! {
329        /// Set the padding type.
330        fn with_padding(padding: Padding);
331        /// Set the manner in which the month is represented.
332        fn with_repr(repr: MonthRepr);
333        /// Set whether the value is case sensitive when parsing.
334        fn with_case_sensitive(case_sensitive: bool);
335    }
336}
337
338/// Ordinal day of the year.
339#[non_exhaustive]
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
341pub struct Ordinal {
342    /// The padding to obtain the minimum width.
343    pub padding: Padding,
344}
345
346impl Ordinal {
347    builder_methods! {
348        /// Set the padding type.
349        fn with_padding(padding: Padding);
350    }
351}
352
353/// The representation used for the day of the week.
354#[non_exhaustive]
355#[deprecated(
356    since = "0.3.48",
357    note = "used only in the deprecated `Weekday` component"
358)]
359#[derive(Debug, Clone, Copy, PartialEq, Eq)]
360pub enum WeekdayRepr {
361    /// The short form of the weekday (e.g. "Mon").
362    Short,
363    /// The long form of the weekday (e.g. "Monday").
364    Long,
365    /// A numerical representation using Sunday as the first day of the week.
366    ///
367    /// Sunday is either 0 or 1, depending on the other modifier's value.
368    Sunday,
369    /// A numerical representation using Monday as the first day of the week.
370    ///
371    /// Monday is either 0 or 1, depending on the other modifier's value.
372    Monday,
373}
374
375/// Day of the week using the short form of the weekday (e.g. "Mon").
376#[derive(Debug, Clone, Copy, PartialEq, Eq)]
377pub struct WeekdayShort {
378    /// Is the value case sensitive when parsing?
379    pub(crate) case_sensitive: bool,
380}
381
382impl WeekdayShort {
383    builder_methods! {
384        /// Set whether the value is case sensitive when parsing.
385        fn with_case_sensitive(case_sensitive: bool);
386    }
387}
388
389/// Day of the week using the long form of the weekday (e.g. "Monday").
390#[derive(Debug, Clone, Copy, PartialEq, Eq)]
391pub struct WeekdayLong {
392    /// Is the value case sensitive when parsing?
393    pub(crate) case_sensitive: bool,
394}
395
396impl WeekdayLong {
397    builder_methods! {
398        /// Set whether the value is case sensitive when parsing.
399        fn with_case_sensitive(case_sensitive: bool);
400    }
401}
402
403/// Day of the week using a numerical representation with Sunday as the first day of the week.
404#[derive(Debug, Clone, Copy, PartialEq, Eq)]
405pub struct WeekdaySunday {
406    /// Is the value zero or one-indexed?
407    pub(crate) one_indexed: bool,
408}
409
410impl WeekdaySunday {
411    builder_methods! {
412        /// Set whether the value is one-indexed.
413        fn with_one_indexed(one_indexed: bool);
414    }
415}
416
417/// Day of the week using a numerical representation with Monday as the first day of the week.
418#[derive(Debug, Clone, Copy, PartialEq, Eq)]
419pub struct WeekdayMonday {
420    /// Is the value zero or one-indexed?
421    pub(crate) one_indexed: bool,
422}
423
424impl WeekdayMonday {
425    builder_methods! {
426        /// Set whether the value is one-indexed.
427        fn with_one_indexed(one_indexed: bool);
428    }
429}
430
431/// Day of the week.
432#[non_exhaustive]
433#[allow(deprecated)]
434#[deprecated(
435    since = "0.3.48",
436    note = "use `WeekdayShort`, `WeekdayLong`, `WeekdaySunday`, or `WeekdayMonday` instead"
437)]
438#[derive(Debug, Clone, Copy, PartialEq, Eq)]
439pub struct Weekday {
440    /// What form of representation should be used?
441    pub repr: WeekdayRepr,
442    /// When using a numerical representation, should it be zero or one-indexed?
443    pub one_indexed: bool,
444    /// Is the value case sensitive when parsing?
445    pub case_sensitive: bool,
446}
447
448#[expect(deprecated)]
449impl Weekday {
450    builder_methods! {
451        /// Set the manner in which the weekday is represented.
452        fn with_repr(repr: WeekdayRepr);
453        /// Set whether the value is one-indexed when using a numerical representation.
454        fn with_one_indexed(one_indexed: bool);
455        /// Set whether the value is case sensitive when parsing.
456        fn with_case_sensitive(case_sensitive: bool);
457    }
458}
459
460/// The representation used for the week number.
461#[non_exhaustive]
462#[deprecated(
463    since = "0.3.48",
464    note = "used only in the deprecated `WeekNumber` component"
465)]
466#[derive(Debug, Clone, Copy, PartialEq, Eq)]
467pub enum WeekNumberRepr {
468    /// Week 1 is the week that contains January 4.
469    Iso,
470    /// Week 1 begins on the first Sunday of the calendar year.
471    Sunday,
472    /// Week 1 begins on the first Monday of the calendar year.
473    Monday,
474}
475
476/// Week within the year using the ISO week calendar.
477///
478/// Week 1 is the week that contains January 4. All weeks begin on a Monday.
479#[derive(Debug, Clone, Copy, PartialEq, Eq)]
480pub struct WeekNumberIso {
481    /// The padding to obtain the minimum width.
482    pub padding: Padding,
483}
484
485impl WeekNumberIso {
486    builder_methods! {
487        /// Set the padding type.
488        fn with_padding(padding: Padding);
489    }
490}
491
492/// Week within the calendar year.
493///
494/// Week 1 begins on the first Sunday of the calendar year.
495#[derive(Debug, Clone, Copy, PartialEq, Eq)]
496pub struct WeekNumberSunday {
497    /// The padding to obtain the minimum width.
498    pub padding: Padding,
499}
500
501impl WeekNumberSunday {
502    builder_methods! {
503        /// Set the padding type.
504        fn with_padding(padding: Padding);
505    }
506}
507
508/// Week within the calendar year.
509///
510/// Week 1 begins on the first Monday of the calendar year.
511#[derive(Debug, Clone, Copy, PartialEq, Eq)]
512pub struct WeekNumberMonday {
513    /// The padding to obtain the minimum width.
514    pub padding: Padding,
515}
516
517impl WeekNumberMonday {
518    builder_methods! {
519        /// Set the padding type.
520        fn with_padding(padding: Padding);
521    }
522}
523
524/// Week within the year.
525#[non_exhaustive]
526#[allow(deprecated)]
527#[deprecated(
528    since = "0.3.48",
529    note = "use `WeekNumberIso`, `WeekNumberSunday`, or `WeekNumberMonday` instead"
530)]
531#[derive(Debug, Clone, Copy, PartialEq, Eq)]
532pub struct WeekNumber {
533    /// The padding to obtain the minimum width.
534    pub padding: Padding,
535    /// What kind of representation should be used?
536    pub repr: WeekNumberRepr,
537}
538
539#[expect(deprecated)]
540impl WeekNumber {
541    builder_methods! {
542        /// Set the padding type.
543        fn with_padding(padding: Padding);
544        /// Set the manner in which the week number is represented.
545        fn with_repr(repr: WeekNumberRepr);
546    }
547}
548
549/// The representation used for a year value.
550#[non_exhaustive]
551#[deprecated(
552    since = "0.3.48",
553    note = "used only in the deprecated `Year` component"
554)]
555#[derive(Debug, Clone, Copy, PartialEq, Eq)]
556pub enum YearRepr {
557    /// The full value of the year.
558    Full,
559    /// All digits except the last two. Includes the sign, if any.
560    Century,
561    /// Only the last two digits of the year.
562    LastTwo,
563}
564
565/// The range of years that are supported.
566///
567/// This modifier has no effect when the year repr is [`LastTwo`](YearRepr::LastTwo).
568#[non_exhaustive]
569#[deprecated(
570    since = "0.3.48",
571    note = "used only in the deprecated `Year` component"
572)]
573#[derive(Debug, Clone, Copy, PartialEq, Eq)]
574pub enum YearRange {
575    /// Years between -9999 and 9999 are supported.
576    Standard,
577    /// Years between -999_999 and 999_999 are supported, with the sign being required if the year
578    /// contains more than four digits.
579    ///
580    /// If the `large-dates` feature is not enabled, this variant is equivalent to `Standard`.
581    Extended,
582}
583
584/// Year of the date. All digits are included, the calendar year is used, and the range of years
585/// supported is ±999,999.
586#[derive(Debug, Clone, Copy, PartialEq, Eq)]
587pub struct CalendarYearFullExtendedRange {
588    /// The padding to obtain the minimum width.
589    pub(crate) padding: Padding,
590    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
591    /// necessary.
592    pub(crate) sign_is_mandatory: bool,
593}
594
595impl CalendarYearFullExtendedRange {
596    builder_methods! {
597        /// Set the padding type.
598        fn with_padding(padding: Padding);
599        /// Set whether the `+` sign is mandatory for non-negative years with more than four digits.
600        fn with_sign_is_mandatory(sign_is_mandatory: bool);
601    }
602}
603
604/// Year of the date. All digits are included, the calendar year is used, and the range of years
605/// supported is ±9,999.
606#[derive(Debug, Clone, Copy, PartialEq, Eq)]
607pub struct CalendarYearFullStandardRange {
608    /// The padding to obtain the minimum width.
609    pub(crate) padding: Padding,
610    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
611    /// necessary.
612    pub(crate) sign_is_mandatory: bool,
613}
614
615impl CalendarYearFullStandardRange {
616    builder_methods! {
617        /// Set the padding type.
618        fn with_padding(padding: Padding);
619        /// Set whether the `+` sign is present on non-negative years.
620        fn with_sign_is_mandatory(sign_is_mandatory: bool);
621    }
622}
623
624/// Year of the date. All digits are included, the ISO week-numbering year is used, and the range of
625/// years supported is ±999,999.
626#[derive(Debug, Clone, Copy, PartialEq, Eq)]
627pub struct IsoYearFullExtendedRange {
628    /// The padding to obtain the minimum width.
629    pub(crate) padding: Padding,
630    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
631    /// necessary.
632    pub(crate) sign_is_mandatory: bool,
633}
634
635impl IsoYearFullExtendedRange {
636    builder_methods! {
637        /// Set the padding type.
638        fn with_padding(padding: Padding);
639        /// Set whether the `+` sign is mandatory for non-negative years with more than four digits.
640        fn with_sign_is_mandatory(sign_is_mandatory: bool);
641    }
642}
643
644/// Year of the date. All digits are included, the ISO week-numbering year is used, and the range of
645/// supported is ±9,999.
646#[derive(Debug, Clone, Copy, PartialEq, Eq)]
647pub struct IsoYearFullStandardRange {
648    /// The padding to obtain the minimum width.
649    pub(crate) padding: Padding,
650    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
651    /// necessary.
652    pub(crate) sign_is_mandatory: bool,
653}
654
655impl IsoYearFullStandardRange {
656    builder_methods! {
657        /// Set the padding type.
658        fn with_padding(padding: Padding);
659        /// Set whether the `+` sign is present on non-negative years.
660        fn with_sign_is_mandatory(sign_is_mandatory: bool);
661    }
662}
663
664/// Year of the date. Only the century is included (i.e. all digits except the last two), the
665/// calendar year is used, and the range of years supported is ±999,999.
666#[derive(Debug, Clone, Copy, PartialEq, Eq)]
667pub struct CalendarYearCenturyExtendedRange {
668    /// The padding to obtain the minimum width.
669    pub(crate) padding: Padding,
670    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
671    /// necessary.
672    pub(crate) sign_is_mandatory: bool,
673}
674
675impl CalendarYearCenturyExtendedRange {
676    builder_methods! {
677        /// Set the padding type.
678        fn with_padding(padding: Padding);
679        /// Set whether the `+` sign is mandatory for non-negative years with more than four digits.
680        fn with_sign_is_mandatory(sign_is_mandatory: bool);
681    }
682}
683
684/// Year of the date. Only the century is included (i.e. all digits except the last two), the
685/// calendar year is used, and the range of years supported is ±9,999.
686#[derive(Debug, Clone, Copy, PartialEq, Eq)]
687pub struct CalendarYearCenturyStandardRange {
688    /// The padding to obtain the minimum width.
689    pub(crate) padding: Padding,
690    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
691    /// necessary.
692    pub(crate) sign_is_mandatory: bool,
693}
694
695impl CalendarYearCenturyStandardRange {
696    builder_methods! {
697        /// Set the padding type.
698        fn with_padding(padding: Padding);
699        /// Set whether the `+` sign is present on non-negative years.
700        fn with_sign_is_mandatory(sign_is_mandatory: bool);
701    }
702}
703
704/// Year of the date. Only the century is included (i.e. all digits except the last two), the ISO
705/// week-numbering year is used, and the range of years supported is ±999,999.
706#[derive(Debug, Clone, Copy, PartialEq, Eq)]
707pub struct IsoYearCenturyExtendedRange {
708    /// The padding to obtain the minimum width.
709    pub(crate) padding: Padding,
710    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
711    /// necessary.
712    pub(crate) sign_is_mandatory: bool,
713}
714
715impl IsoYearCenturyExtendedRange {
716    builder_methods! {
717        /// Set the padding type.
718        fn with_padding(padding: Padding);
719        /// Set whether the `+` sign is mandatory for non-negative years with more than four digits.
720        fn with_sign_is_mandatory(sign_is_mandatory: bool);
721    }
722}
723
724/// Year of the date. Only the century is included (i.e. all digits except the last two), the ISO
725/// week-numbering year is used, and the range of years supported is ±9,999.
726#[derive(Debug, Clone, Copy, PartialEq, Eq)]
727pub struct IsoYearCenturyStandardRange {
728    /// The padding to obtain the minimum width.
729    pub(crate) padding: Padding,
730    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
731    /// necessary.
732    pub(crate) sign_is_mandatory: bool,
733}
734
735impl IsoYearCenturyStandardRange {
736    builder_methods! {
737        /// Set the padding type.
738        fn with_padding(padding: Padding);
739        /// Set whether the `+` sign is present on non-negative years.
740        fn with_sign_is_mandatory(sign_is_mandatory: bool);
741    }
742}
743
744/// Year of the date. Only the last two digits are included, and the calendar year is used.
745#[non_exhaustive]
746#[derive(Debug, Clone, Copy, PartialEq, Eq)]
747pub struct CalendarYearLastTwo {
748    /// The padding to obtain the minimum width.
749    pub(crate) padding: Padding,
750}
751
752impl CalendarYearLastTwo {
753    builder_methods! {
754        /// Set the padding type.
755        fn with_padding(padding: Padding);
756    }
757}
758
759/// Year of the date. Only the last two digits are included, and the ISO week-numbering year is
760/// used.
761#[non_exhaustive]
762#[derive(Debug, Clone, Copy, PartialEq, Eq)]
763pub struct IsoYearLastTwo {
764    /// The padding to obtain the minimum width.
765    pub(crate) padding: Padding,
766}
767
768impl IsoYearLastTwo {
769    builder_methods! {
770        /// Set the padding type.
771        fn with_padding(padding: Padding);
772    }
773}
774
775/// Year of the date.
776#[non_exhaustive]
777#[allow(deprecated)]
778#[deprecated(
779    since = "0.3.48",
780    note = "use one of the various `Year*` components instead"
781)]
782#[derive(Debug, Clone, Copy, PartialEq, Eq)]
783pub struct Year {
784    /// The padding to obtain the minimum width.
785    pub padding: Padding,
786    /// What kind of representation should be used?
787    pub repr: YearRepr,
788    /// What range of years is supported?
789    pub range: YearRange,
790    /// Whether the value is based on the ISO week number or the Gregorian calendar.
791    pub iso_week_based: bool,
792    /// Whether the `+` sign is present when a non-negative year contains fewer digits than
793    /// necessary.
794    pub sign_is_mandatory: bool,
795}
796
797#[expect(deprecated)]
798impl Year {
799    builder_methods! {
800        /// Set the padding type.
801        fn with_padding(padding: Padding);
802        /// Set the manner in which the year is represented.
803        fn with_repr(repr: YearRepr);
804        /// Set the range of years that are supported.
805        fn with_range(range: YearRange);
806        /// Set whether the year is based on the ISO week number.
807        fn with_iso_week_based(iso_week_based: bool);
808        /// Set whether the `+` sign is mandatory for positive years with fewer than five digits.
809        fn with_sign_is_mandatory(sign_is_mandatory: bool);
810    }
811}
812
813/// Hour of the day using a 12-hour clock.
814#[derive(Debug, Clone, Copy, PartialEq, Eq)]
815pub struct Hour12 {
816    /// The padding to obtain the minimum width.
817    pub(crate) padding: Padding,
818}
819
820impl Hour12 {
821    builder_methods! {
822        /// Set the padding type.
823        fn with_padding(padding: Padding);
824    }
825}
826
827/// Hour of the day using a 24-hour clock.
828#[derive(Debug, Clone, Copy, PartialEq, Eq)]
829pub struct Hour24 {
830    /// The padding to obtain the minimum width.
831    pub(crate) padding: Padding,
832}
833
834impl Hour24 {
835    builder_methods! {
836        /// Set the padding type.
837        fn with_padding(padding: Padding);
838    }
839}
840
841/// Hour of the day.
842#[non_exhaustive]
843#[deprecated(since = "0.3.48", note = "use `Hour12` or `Hour24` instead")]
844#[derive(Debug, Clone, Copy, PartialEq, Eq)]
845pub struct Hour {
846    /// The padding to obtain the minimum width.
847    pub padding: Padding,
848    /// Is the hour displayed using a 12 or 24-hour clock?
849    pub is_12_hour_clock: bool,
850}
851
852#[expect(deprecated)]
853impl Hour {
854    builder_methods! {
855        /// Set the padding type.
856        fn with_padding(padding: Padding);
857        /// Set whether the hour uses a 12-hour clock.
858        fn with_is_12_hour_clock(is_12_hour_clock: bool);
859    }
860}
861
862/// Minute within the hour.
863#[non_exhaustive]
864#[derive(Debug, Clone, Copy, PartialEq, Eq)]
865pub struct Minute {
866    /// The padding to obtain the minimum width.
867    pub padding: Padding,
868}
869
870impl Minute {
871    builder_methods! {
872        /// Set the padding type.
873        fn with_padding(padding: Padding);
874    }
875}
876
877/// AM/PM part of the time.
878#[non_exhaustive]
879#[derive(Debug, Clone, Copy, PartialEq, Eq)]
880pub struct Period {
881    /// Is the period uppercase or lowercase?
882    pub is_uppercase: bool,
883    /// Is the value case sensitive when parsing?
884    ///
885    /// Note that when `false`, the `is_uppercase` field has no effect on parsing behavior.
886    pub case_sensitive: bool,
887}
888
889impl Period {
890    builder_methods! {
891        /// Set whether the period is uppercase.
892        fn with_is_uppercase(is_uppercase: bool);
893        /// Set whether the value is case sensitive when parsing.
894        fn with_case_sensitive(case_sensitive: bool);
895    }
896}
897
898/// Second within the minute.
899#[non_exhaustive]
900#[derive(Debug, Clone, Copy, PartialEq, Eq)]
901pub struct Second {
902    /// The padding to obtain the minimum width.
903    pub padding: Padding,
904}
905
906impl Second {
907    builder_methods! {
908        /// Set the padding type.
909        fn with_padding(padding: Padding);
910    }
911}
912
913/// The number of digits present in a subsecond representation.
914#[non_exhaustive]
915#[derive(Debug, Clone, Copy, PartialEq, Eq)]
916pub enum SubsecondDigits {
917    /// Exactly one digit.
918    One,
919    /// Exactly two digits.
920    Two,
921    /// Exactly three digits.
922    Three,
923    /// Exactly four digits.
924    Four,
925    /// Exactly five digits.
926    Five,
927    /// Exactly six digits.
928    Six,
929    /// Exactly seven digits.
930    Seven,
931    /// Exactly eight digits.
932    Eight,
933    /// Exactly nine digits.
934    Nine,
935    /// Any number of digits (up to nine) that is at least one. When formatting, the minimum digits
936    /// necessary will be used.
937    OneOrMore,
938}
939
940/// Subsecond within the second.
941#[non_exhaustive]
942#[derive(Debug, Clone, Copy, PartialEq, Eq)]
943pub struct Subsecond {
944    /// How many digits are present in the component?
945    pub digits: SubsecondDigits,
946}
947
948impl Subsecond {
949    builder_methods! {
950        /// Set the number of digits present in the subsecond representation.
951        fn with_digits(digits: SubsecondDigits);
952    }
953}
954
955/// Hour of the UTC offset.
956#[non_exhaustive]
957#[derive(Debug, Clone, Copy, PartialEq, Eq)]
958pub struct OffsetHour {
959    /// Whether the `+` sign is present on positive values.
960    pub sign_is_mandatory: bool,
961    /// The padding to obtain the minimum width.
962    pub padding: Padding,
963}
964
965impl OffsetHour {
966    builder_methods! {
967        /// Set whether the `+` sign is mandatory for positive values.
968        fn with_sign_is_mandatory(sign_is_mandatory: bool);
969        /// Set the padding type.
970        fn with_padding(padding: Padding);
971    }
972}
973
974/// Minute within the hour of the UTC offset.
975#[non_exhaustive]
976#[derive(Debug, Clone, Copy, PartialEq, Eq)]
977pub struct OffsetMinute {
978    /// The padding to obtain the minimum width.
979    pub padding: Padding,
980}
981
982impl OffsetMinute {
983    builder_methods! {
984        /// Set the padding type.
985        fn with_padding(padding: Padding);
986    }
987}
988
989/// Second within the minute of the UTC offset.
990#[non_exhaustive]
991#[derive(Debug, Clone, Copy, PartialEq, Eq)]
992pub struct OffsetSecond {
993    /// The padding to obtain the minimum width.
994    pub padding: Padding,
995}
996
997impl OffsetSecond {
998    builder_methods! {
999        /// Set the padding type.
1000        fn with_padding(padding: Padding);
1001    }
1002}
1003
1004/// Type of padding to ensure a minimum width.
1005#[non_exhaustive]
1006#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1007pub enum Padding {
1008    /// A space character (` `) should be used as padding.
1009    Space,
1010    /// A zero character (`0`) should be used as padding.
1011    Zero,
1012    /// There is no padding. This can result in a width below the otherwise minimum number of
1013    /// characters.
1014    None,
1015}
1016
1017/// Ignore some number of bytes.
1018///
1019/// This has no effect when formatting.
1020#[non_exhaustive]
1021#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1022pub struct Ignore {
1023    /// The number of bytes to ignore.
1024    pub count: NonZero<u16>,
1025}
1026
1027// Needed as `Default` is deliberately not implemented for `Ignore`. The number of bytes to ignore
1028// must be explicitly provided.
1029impl Ignore {
1030    /// Create an instance of `Ignore` with the provided number of bytes to ignore.
1031    #[inline]
1032    pub const fn count(count: NonZero<u16>) -> Self {
1033        Self { count }
1034    }
1035
1036    builder_methods! {
1037        /// Set the number of bytes to ignore.
1038        fn with_count(count: NonZero<u16>);
1039    }
1040}
1041
1042/// The precision of a Unix timestamp.
1043#[non_exhaustive]
1044#[deprecated(
1045    since = "0.3.48",
1046    note = "only used in the deprecated `UnixTimestamp` component"
1047)]
1048#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1049pub enum UnixTimestampPrecision {
1050    /// Seconds since the Unix epoch.
1051    Second,
1052    /// Milliseconds since the Unix epoch.
1053    Millisecond,
1054    /// Microseconds since the Unix epoch.
1055    Microsecond,
1056    /// Nanoseconds since the Unix epoch.
1057    Nanosecond,
1058}
1059
1060/// A Unix timestamp in seconds.
1061#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1062pub struct UnixTimestampSecond {
1063    /// Whether the `+` sign must be present for a non-negative timestamp.
1064    pub(crate) sign_is_mandatory: bool,
1065}
1066
1067impl UnixTimestampSecond {
1068    builder_methods! {
1069        /// Set whether the `+` sign is mandatory for non-negative timestamps.
1070        fn with_sign_is_mandatory(sign_is_mandatory: bool);
1071    }
1072}
1073
1074/// A Unix timestamp in milliseconds.
1075#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1076pub struct UnixTimestampMillisecond {
1077    /// Whether the `+` sign must be present for a non-negative timestamp.
1078    pub(crate) sign_is_mandatory: bool,
1079}
1080
1081impl UnixTimestampMillisecond {
1082    builder_methods! {
1083        /// Set whether the `+` sign is mandatory for non-negative timestamps.
1084        fn with_sign_is_mandatory(sign_is_mandatory: bool);
1085    }
1086}
1087
1088/// A Unix timestamp in microseconds.
1089#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1090pub struct UnixTimestampMicrosecond {
1091    /// Whether the `+` sign must be present for a non-negative timestamp.
1092    pub(crate) sign_is_mandatory: bool,
1093}
1094
1095impl UnixTimestampMicrosecond {
1096    builder_methods! {
1097        /// Set whether the `+` sign is mandatory for non-negative timestamps.
1098        fn with_sign_is_mandatory(sign_is_mandatory: bool);
1099    }
1100}
1101
1102/// A Unix timestamp in nanoseconds.
1103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1104pub struct UnixTimestampNanosecond {
1105    /// Whether the `+` sign must be present for a non-negative timestamp.
1106    pub(crate) sign_is_mandatory: bool,
1107}
1108
1109impl UnixTimestampNanosecond {
1110    builder_methods! {
1111        /// Set whether the `+` sign is mandatory for non-negative timestamps.
1112        fn with_sign_is_mandatory(sign_is_mandatory: bool);
1113    }
1114}
1115
1116/// A Unix timestamp.
1117#[non_exhaustive]
1118#[allow(deprecated)]
1119#[deprecated(
1120    since = "0.3.48",
1121    note = "use `UnixTimestampSeconds`, `UnixTimestampMilliseconds`, `UnixTimestampMicroseconds`, \
1122            or `UnixTimestampNanoseconds` instead"
1123)]
1124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1125pub struct UnixTimestamp {
1126    /// The precision of the timestamp.
1127    pub precision: UnixTimestampPrecision,
1128    /// Whether the `+` sign must be present for a non-negative timestamp.
1129    pub sign_is_mandatory: bool,
1130}
1131
1132#[expect(deprecated)]
1133impl UnixTimestamp {
1134    builder_methods! {
1135        /// Set the precision of the timestamp.
1136        fn with_precision(precision: UnixTimestampPrecision);
1137        /// Set whether the `+` sign is mandatory for non-negative timestamps.
1138        fn with_sign_is_mandatory(sign_is_mandatory: bool);
1139    }
1140}
1141
1142/// Whether trailing input after the declared end is permitted.
1143#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1144pub enum TrailingInput {
1145    /// Trailing input is not permitted and will cause an error.
1146    Prohibit,
1147    /// Trailing input is permitted but discarded.
1148    Discard,
1149}
1150
1151/// The end of input.
1152#[non_exhaustive]
1153#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1154pub struct End {
1155    /// How to handle any input after this component.
1156    pub(crate) trailing_input: TrailingInput,
1157}
1158
1159impl End {
1160    builder_methods! {
1161        /// Set how to handle any input after this component.
1162        fn with_trailing_input(trailing_input: TrailingInput);
1163    }
1164}