@@ -68,8 +68,152 @@ impl PartialDuration {
6868
6969/// The native Rust implementation of `Temporal.Duration`.
7070///
71- /// `Duration` is made up of a `DateDuration` and `TimeDuration` as primarily
72- /// defined by Abtract Operation 7.5.1-5.
71+ /// Represents a span of time such as "2 hours and 30 minutes" or "3 years, 2 months".
72+ /// Unlike `Instant` which represents a specific moment in time, Duration represents
73+ /// the amount of time between two moments.
74+ ///
75+ /// A Duration consists of two categories of components:
76+ /// - Date components: years, months, weeks, and days
77+ /// - Time components: hours, minutes, seconds, and subsecond units (nanosecond precision)
78+ ///
79+ /// Note that date arithmetic can be complex. For example, adding "1 month" to January 31st
80+ /// could result in February 28th (non-leap year), February 29th (leap year), or March 3rd
81+ /// (if you overflow February), depending on the calendar system and overflow handling.
82+ ///
83+ /// ## Examples
84+ ///
85+ /// ### Creating durations
86+ ///
87+ /// ```rust
88+ /// use temporal_rs::Duration;
89+ ///
90+ /// // Create a duration with specific components
91+ /// let vacation_duration = Duration::new(
92+ /// 0, 0, 2, 3, // 2 weeks and 3 days
93+ /// 0, 0, 0, // no time components
94+ /// 0, 0, 0 // no subsecond components
95+ /// ).unwrap();
96+ ///
97+ /// assert_eq!(vacation_duration.weeks(), 2);
98+ /// assert_eq!(vacation_duration.days(), 3);
99+ /// ```
100+ ///
101+ /// ### Parsing ISO 8601 duration strings
102+ ///
103+ /// ```rust
104+ /// use temporal_rs::Duration;
105+ /// use core::str::FromStr;
106+ ///
107+ /// // Complex duration with multiple components
108+ /// let complex = Duration::from_str("P1Y2M3DT4H5M6.789S").unwrap();
109+ /// assert_eq!(complex.years(), 1);
110+ /// assert_eq!(complex.months(), 2);
111+ /// assert_eq!(complex.days(), 3);
112+ /// assert_eq!(complex.hours(), 4);
113+ /// assert_eq!(complex.minutes(), 5);
114+ /// assert_eq!(complex.seconds(), 6);
115+ ///
116+ /// // Time-only duration
117+ /// let movie_length = Duration::from_str("PT2H30M").unwrap();
118+ /// assert_eq!(movie_length.hours(), 2);
119+ /// assert_eq!(movie_length.minutes(), 30);
120+ ///
121+ /// // Negative durations
122+ /// let negative = Duration::from_str("-P1D").unwrap();
123+ /// assert_eq!(negative.days(), -1);
124+ /// ```
125+ ///
126+ /// ### Duration arithmetic
127+ ///
128+ /// ```rust
129+ /// use temporal_rs::Duration;
130+ /// use core::str::FromStr;
131+ ///
132+ /// let commute_time = Duration::from_str("PT45M").unwrap();
133+ /// let lunch_break = Duration::from_str("PT1H").unwrap();
134+ ///
135+ /// // Add durations together
136+ /// let total_time = commute_time.add(&lunch_break).unwrap();
137+ /// assert_eq!(total_time.hours(), 1); // Results in 1 hour 45 minutes
138+ /// assert_eq!(total_time.minutes(), 45);
139+ ///
140+ /// // Subtract duration components
141+ /// let shortened = lunch_break.subtract(&Duration::from_str("PT15M").unwrap()).unwrap();
142+ /// assert_eq!(shortened.minutes(), 45);
143+ /// ```
144+ ///
145+ /// ### Date arithmetic with durations
146+ ///
147+ /// ```rust
148+ /// use temporal_rs::{PlainDate, Duration, options::ArithmeticOverflow};
149+ /// use core::str::FromStr;
150+ ///
151+ /// // January 31st in different years
152+ /// let jan_31_2023 = PlainDate::try_new_iso(2023, 1, 31).unwrap();
153+ /// let jan_31_2024 = PlainDate::try_new_iso(2024, 1, 31).unwrap(); // leap year
154+ ///
155+ /// let one_month = Duration::from_str("P1M").unwrap();
156+ ///
157+ /// // Adding 1 month to Jan 31st gives different results:
158+ /// let feb_2023 = jan_31_2023.add(&one_month, Some(ArithmeticOverflow::Constrain)).unwrap();
159+ /// let feb_2024 = jan_31_2024.add(&one_month, Some(ArithmeticOverflow::Constrain)).unwrap();
160+ ///
161+ /// // 2023: Jan 31 + 1 month = Feb 28 (no Feb 31st exists)
162+ /// assert_eq!(feb_2023.day(), 28);
163+ /// // 2024: Jan 31 + 1 month = Feb 29 (leap year)
164+ /// assert_eq!(feb_2024.day(), 29);
165+ /// ```
166+ ///
167+ /// ### Working with partial durations
168+ ///
169+ /// ```rust
170+ /// use temporal_rs::{Duration, partial::PartialDuration};
171+ ///
172+ /// let partial = PartialDuration {
173+ /// hours: Some(3),
174+ /// minutes: Some(45),
175+ /// ..Default::default()
176+ /// };
177+ ///
178+ /// let duration = Duration::from_partial_duration(partial).unwrap();
179+ /// assert_eq!(duration.hours(), 3);
180+ /// assert_eq!(duration.minutes(), 45);
181+ /// assert_eq!(duration.days(), 0); // other fields default to 0
182+ /// ```
183+ ///
184+ /// ### Duration properties
185+ ///
186+ /// ```rust
187+ /// use temporal_rs::Duration;
188+ /// use core::str::FromStr;
189+ ///
190+ /// let duration = Duration::from_str("P1Y2M3D").unwrap();
191+ ///
192+ /// // Check if duration is zero
193+ /// assert!(!duration.is_zero());
194+ ///
195+ /// // Get the sign of the duration
196+ /// let sign = duration.sign();
197+ /// // Note: This particular duration has mixed signs which affects the overall sign
198+ ///
199+ /// // Get absolute value
200+ /// let abs_duration = duration.abs();
201+ /// assert_eq!(abs_duration.years(), 1);
202+ /// assert_eq!(abs_duration.months(), 2);
203+ /// assert_eq!(abs_duration.days(), 3);
204+ ///
205+ /// // Negate duration
206+ /// let negated = duration.negated();
207+ /// assert_eq!(negated.years(), -1);
208+ /// assert_eq!(negated.months(), -2);
209+ /// assert_eq!(negated.days(), -3);
210+ /// ```
211+ ///
212+ /// ## Reference
213+ ///
214+ /// For more information, see the [MDN documentation][mdn-duration].
215+ ///
216+ /// [mdn-duration]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration
73217#[ non_exhaustive]
74218#[ derive( Debug , Clone , Copy , Default ) ]
75219pub struct Duration {
0 commit comments