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}