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