1 // This is a part of Chrono.
2 // See README.md and LICENSE.txt for details.
3
4 //! # Chrono: Date and Time for Rust
5 //!
6 //! It aims to be a feature-complete superset of
7 //! the [time](https://github.com/rust-lang-deprecated/time) library.
8 //! In particular,
9 //!
10 //! * Chrono strictly adheres to ISO 8601.
11 //! * Chrono is timezone-aware by default, with separate timezone-naive types.
12 //! * Chrono is space-optimal and (while not being the primary goal) reasonably efficient.
13 //!
14 //! There were several previous attempts to bring a good date and time library to Rust,
15 //! which Chrono builds upon and should acknowledge:
16 //!
17 //! * [Initial research on
18 //! the wiki](https://github.com/rust-lang/rust-wiki-backup/blob/master/Lib-datetime.md)
19 //! * Dietrich Epp's [datetime-rs](https://github.com/depp/datetime-rs)
20 //! * Luis de Bethencourt's [rust-datetime](https://github.com/luisbg/rust-datetime)
21 //!
22 //! Any significant changes to Chrono are documented in
23 //! the [`CHANGELOG.md`](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) file.
24 //!
25 //! ## Usage
26 //!
27 //! Put this in your `Cargo.toml`:
28 //!
29 //! ```toml
30 //! [dependencies]
31 //! chrono = "0.4"
32 //! ```
33 //!
34 //! ### Features
35 //!
36 //! Chrono supports various runtime environments and operating systems, and has
37 //! several features that may be enabled or disabled.
38 //!
39 //! Default features:
40 //!
41 //! - `alloc`: Enable features that depend on allocation (primarily string formatting)
42 //! - `std`: Enables functionality that depends on the standard library. This
43 //! is a superset of `alloc` and adds interoperation with standard library types
44 //! and traits.
45 //! - `clock`: enables reading the system time (`now`), independent of whether
46 //! `std::time::SystemTime` is present, depends on having a libc.
47 //!
48 //! Optional features:
49 //!
50 //! - `wasmbind`: Enable integration with [wasm-bindgen][] and its `js-sys` project
51 //! - [`serde`][]: Enable serialization/deserialization via serde.
52 //! - `unstable-locales`: Enable localization. This adds various methods with a
53 //! `_localized` suffix. The implementation and API may change or even be
54 //! removed in a patch release. Feedback welcome.
55 //!
56 //! [`serde`]: https://github.com/serde-rs/serde
57 //! [wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen
58 //!
59 //! See the [cargo docs][] for examples of specifying features.
60 //!
61 //! [cargo docs]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#choosing-features
62 //!
63 //! ## Overview
64 //!
65 //! ### Duration
66 //!
67 //! Chrono currently uses its own [`Duration`] type to represent the magnitude
68 //! of a time span. Since this has the same name as the newer, standard type for
69 //! duration, the reference will refer this type as `OldDuration`.
70 //!
71 //! Note that this is an "accurate" duration represented as seconds and
72 //! nanoseconds and does not represent "nominal" components such as days or
73 //! months.
74 //!
75 //! When the `oldtime` feature is enabled, [`Duration`] is an alias for the
76 //! [`time::Duration`](https://docs.rs/time/0.1.40/time/struct.Duration.html)
77 //! type from v0.1 of the time crate. time v0.1 is deprecated, so new code
78 //! should disable the `oldtime` feature and use the `chrono::Duration` type
79 //! instead. The `oldtime` feature is enabled by default for backwards
80 //! compatibility, but future versions of Chrono are likely to remove the
81 //! feature entirely.
82 //!
83 //! Chrono does not yet natively support
84 //! the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type,
85 //! but it will be supported in the future.
86 //! Meanwhile you can convert between two types with
87 //! [`Duration::from_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.from_std)
88 //! and
89 //! [`Duration::to_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.to_std)
90 //! methods.
91 //!
92 //! ### Date and Time
93 //!
94 //! Chrono provides a
95 //! [**`DateTime`**](./struct.DateTime.html)
96 //! type to represent a date and a time in a timezone.
97 //!
98 //! For more abstract moment-in-time tracking such as internal timekeeping
99 //! that is unconcerned with timezones, consider
100 //! [`time::SystemTime`](https://doc.rust-lang.org/std/time/struct.SystemTime.html),
101 //! which tracks your system clock, or
102 //! [`time::Instant`](https://doc.rust-lang.org/std/time/struct.Instant.html), which
103 //! is an opaque but monotonically-increasing representation of a moment in time.
104 //!
105 //! `DateTime` is timezone-aware and must be constructed from
106 //! the [**`TimeZone`**](./offset/trait.TimeZone.html) object,
107 //! which defines how the local date is converted to and back from the UTC date.
108 //! There are three well-known `TimeZone` implementations:
109 //!
110 //! * [**`Utc`**](./offset/struct.Utc.html) specifies the UTC time zone. It is most efficient.
111 //!
112 //! * [**`Local`**](./offset/struct.Local.html) specifies the system local time zone.
113 //!
114 //! * [**`FixedOffset`**](./offset/struct.FixedOffset.html) specifies
115 //! an arbitrary, fixed time zone such as UTC+09:00 or UTC-10:30.
116 //! This often results from the parsed textual date and time.
117 //! Since it stores the most information and does not depend on the system environment,
118 //! you would want to normalize other `TimeZone`s into this type.
119 //!
120 //! `DateTime`s with different `TimeZone` types are distinct and do not mix,
121 //! but can be converted to each other using
122 //! the [`DateTime::with_timezone`](./struct.DateTime.html#method.with_timezone) method.
123 //!
124 //! You can get the current date and time in the UTC time zone
125 //! ([`Utc::now()`](./offset/struct.Utc.html#method.now))
126 //! or in the local time zone
127 //! ([`Local::now()`](./offset/struct.Local.html#method.now)).
128 //!
129 //! ```rust
130 //! use chrono::prelude::*;
131 //!
132 //! let utc: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
133 //! let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
134 //! # let _ = utc; let _ = local;
135 //! ```
136 //!
137 //! Alternatively, you can create your own date and time.
138 //! This is a bit verbose due to Rust's lack of function and method overloading,
139 //! but in turn we get a rich combination of initialization methods.
140 //!
141 //! ```rust
142 //! use chrono::prelude::*;
143 //! use chrono::offset::LocalResult;
144 //!
145 //! let dt = Utc.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z`
146 //! // July 8 is 188th day of the year 2014 (`o` for "ordinal")
147 //! assert_eq!(dt, Utc.yo(2014, 189).and_hms(9, 10, 11));
148 //! // July 8 is Tuesday in ISO week 28 of the year 2014.
149 //! assert_eq!(dt, Utc.isoywd(2014, 28, Weekday::Tue).and_hms(9, 10, 11));
150 //!
151 //! let dt = Utc.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); // `2014-07-08T09:10:11.012Z`
152 //! assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_micro(9, 10, 11, 12_000));
153 //! assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_nano(9, 10, 11, 12_000_000));
154 //!
155 //! // dynamic verification
156 //! assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(21, 15, 33),
157 //! LocalResult::Single(Utc.ymd(2014, 7, 8).and_hms(21, 15, 33)));
158 //! assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None);
159 //! assert_eq!(Utc.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None);
160 //!
161 //! // other time zone objects can be used to construct a local datetime.
162 //! // obviously, `local_dt` is normally different from `dt`, but `fixed_dt` should be identical.
163 //! let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12);
164 //! let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12);
165 //! assert_eq!(dt, fixed_dt);
166 //! # let _ = local_dt;
167 //! ```
168 //!
169 //! Various properties are available to the date and time, and can be altered individually.
170 //! Most of them are defined in the traits [`Datelike`](./trait.Datelike.html) and
171 //! [`Timelike`](./trait.Timelike.html) which you should `use` before.
172 //! Addition and subtraction is also supported.
173 //! The following illustrates most supported operations to the date and time:
174 //!
175 //! ```rust
176 //! # extern crate chrono;
177 //!
178 //! # fn main() {
179 //! use chrono::prelude::*;
180 //! use chrono::Duration;
181 //!
182 //! // assume this returned `2014-11-28T21:45:59.324310806+09:00`:
183 //! let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806);
184 //!
185 //! // property accessors
186 //! assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28));
187 //! assert_eq!((dt.month0(), dt.day0()), (10, 27)); // for unfortunate souls
188 //! assert_eq!((dt.hour(), dt.minute(), dt.second()), (21, 45, 59));
189 //! assert_eq!(dt.weekday(), Weekday::Fri);
190 //! assert_eq!(dt.weekday().number_from_monday(), 5); // Mon=1, ..., Sun=7
191 //! assert_eq!(dt.ordinal(), 332); // the day of year
192 //! assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1
193 //!
194 //! // time zone accessor and manipulation
195 //! assert_eq!(dt.offset().fix().local_minus_utc(), 9 * 3600);
196 //! assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600));
197 //! assert_eq!(dt.with_timezone(&Utc), Utc.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806));
198 //!
199 //! // a sample of property manipulations (validates dynamically)
200 //! assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday
201 //! assert_eq!(dt.with_day(32), None);
202 //! assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE
203 //!
204 //! // arithmetic operations
205 //! let dt1 = Utc.ymd(2014, 11, 14).and_hms(8, 9, 10);
206 //! let dt2 = Utc.ymd(2014, 11, 14).and_hms(10, 9, 8);
207 //! assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2));
208 //! assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2));
209 //! assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000),
210 //! Utc.ymd(2001, 9, 9).and_hms(1, 46, 40));
211 //! assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000),
212 //! Utc.ymd(1938, 4, 24).and_hms(22, 13, 20));
213 //! # }
214 //! ```
215 //!
216 //! ### Formatting and Parsing
217 //!
218 //! Formatting is done via the [`format`](./struct.DateTime.html#method.format) method,
219 //! which format is equivalent to the familiar `strftime` format.
220 //!
221 //! See [`format::strftime`](./format/strftime/index.html#specifiers)
222 //! documentation for full syntax and list of specifiers.
223 //!
224 //! The default `to_string` method and `{:?}` specifier also give a reasonable representation.
225 //! Chrono also provides [`to_rfc2822`](./struct.DateTime.html#method.to_rfc2822) and
226 //! [`to_rfc3339`](./struct.DateTime.html#method.to_rfc3339) methods
227 //! for well-known formats.
228 //!
229 //! Chrono now also provides date formatting in almost any language without the
230 //! help of an additional C library. This functionality is under the feature
231 //! `unstable-locales`:
232 //!
233 //! ```text
234 //! chrono { version = "0.4", features = ["unstable-locales"]
235 //! ```
236 //!
237 //! The `unstable-locales` feature requires and implies at least the `alloc` feature.
238 //!
239 //! ```rust
240 //! use chrono::prelude::*;
241 //!
242 //! let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);
243 //! assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
244 //! assert_eq!(dt.format("%a %b %e %T %Y").to_string(), "Fri Nov 28 12:00:09 2014");
245 //! assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), "vendredi 28 novembre 2014, 12:00:09");
246 //! assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string());
247 //!
248 //! assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC");
249 //! assert_eq!(dt.to_rfc2822(), "Fri, 28 Nov 2014 12:00:09 +0000");
250 //! assert_eq!(dt.to_rfc3339(), "2014-11-28T12:00:09+00:00");
251 //! assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
252 //!
253 //! // Note that milli/nanoseconds are only printed if they are non-zero
254 //! let dt_nano = Utc.ymd(2014, 11, 28).and_hms_nano(12, 0, 9, 1);
255 //! assert_eq!(format!("{:?}", dt_nano), "2014-11-28T12:00:09.000000001Z");
256 //! ```
257 //!
258 //! Parsing can be done with three methods:
259 //!
260 //! 1. The standard [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait
261 //! (and [`parse`](https://doc.rust-lang.org/std/primitive.str.html#method.parse) method
262 //! on a string) can be used for parsing `DateTime<FixedOffset>`, `DateTime<Utc>` and
263 //! `DateTime<Local>` values. This parses what the `{:?}`
264 //! ([`std::fmt::Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html))
265 //! format specifier prints, and requires the offset to be present.
266 //!
267 //! 2. [`DateTime::parse_from_str`](./struct.DateTime.html#method.parse_from_str) parses
268 //! a date and time with offsets and returns `DateTime<FixedOffset>`.
269 //! This should be used when the offset is a part of input and the caller cannot guess that.
270 //! It *cannot* be used when the offset can be missing.
271 //! [`DateTime::parse_from_rfc2822`](./struct.DateTime.html#method.parse_from_rfc2822)
272 //! and
273 //! [`DateTime::parse_from_rfc3339`](./struct.DateTime.html#method.parse_from_rfc3339)
274 //! are similar but for well-known formats.
275 //!
276 //! 3. [`Offset::datetime_from_str`](./offset/trait.TimeZone.html#method.datetime_from_str) is
277 //! similar but returns `DateTime` of given offset.
278 //! When the explicit offset is missing from the input, it simply uses given offset.
279 //! It issues an error when the input contains an explicit offset different
280 //! from the current offset.
281 //!
282 //! More detailed control over the parsing process is available via
283 //! [`format`](./format/index.html) module.
284 //!
285 //! ```rust
286 //! use chrono::prelude::*;
287 //!
288 //! let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);
289 //! let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600));
290 //!
291 //! // method 1
292 //! assert_eq!("2014-11-28T12:00:09Z".parse::<DateTime<Utc>>(), Ok(dt.clone()));
293 //! assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<Utc>>(), Ok(dt.clone()));
294 //! assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<FixedOffset>>(), Ok(fixed_dt.clone()));
295 //!
296 //! // method 2
297 //! assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z"),
298 //! Ok(fixed_dt.clone()));
299 //! assert_eq!(DateTime::parse_from_rfc2822("Fri, 28 Nov 2014 21:00:09 +0900"),
300 //! Ok(fixed_dt.clone()));
301 //! assert_eq!(DateTime::parse_from_rfc3339("2014-11-28T21:00:09+09:00"), Ok(fixed_dt.clone()));
302 //!
303 //! // method 3
304 //! assert_eq!(Utc.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone()));
305 //! assert_eq!(Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone()));
306 //!
307 //! // oops, the year is missing!
308 //! assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());
309 //! // oops, the format string does not include the year at all!
310 //! assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T").is_err());
311 //! // oops, the weekday is incorrect!
312 //! assert!(Utc.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err());
313 //! ```
314 //!
315 //! Again : See [`format::strftime`](./format/strftime/index.html#specifiers)
316 //! documentation for full syntax and list of specifiers.
317 //!
318 //! ### Conversion from and to EPOCH timestamps
319 //!
320 //! Use [`Utc.timestamp(seconds, nanoseconds)`](./offset/trait.TimeZone.html#method.timestamp)
321 //! to construct a [`DateTime<Utc>`](./struct.DateTime.html) from a UNIX timestamp
322 //! (seconds, nanoseconds that passed since January 1st 1970).
323 //!
324 //! Use [`DateTime.timestamp`](./struct.DateTime.html#method.timestamp) to get the timestamp (in seconds)
325 //! from a [`DateTime`](./struct.DateTime.html). Additionally, you can use
326 //! [`DateTime.timestamp_subsec_nanos`](./struct.DateTime.html#method.timestamp_subsec_nanos)
327 //! to get the number of additional number of nanoseconds.
328 //!
329 //! ```rust
330 //! // We need the trait in scope to use Utc::timestamp().
331 //! use chrono::{DateTime, TimeZone, Utc};
332 //!
333 //! // Construct a datetime from epoch:
334 //! let dt = Utc.timestamp(1_500_000_000, 0);
335 //! assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000");
336 //!
337 //! // Get epoch value from a datetime:
338 //! let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap();
339 //! assert_eq!(dt.timestamp(), 1_500_000_000);
340 //! ```
341 //!
342 //! ### Individual date
343 //!
344 //! Chrono also provides an individual date type ([**`Date`**](./struct.Date.html)).
345 //! It also has time zones attached, and have to be constructed via time zones.
346 //! Most operations available to `DateTime` are also available to `Date` whenever appropriate.
347 //!
348 //! ```rust
349 //! use chrono::prelude::*;
350 //! use chrono::offset::LocalResult;
351 //!
352 //! # // these *may* fail, but only very rarely. just rerun the test if you were that unfortunate ;)
353 //! assert_eq!(Utc::today(), Utc::now().date());
354 //! assert_eq!(Local::today(), Local::now().date());
355 //!
356 //! assert_eq!(Utc.ymd(2014, 11, 28).weekday(), Weekday::Fri);
357 //! assert_eq!(Utc.ymd_opt(2014, 11, 31), LocalResult::None);
358 //! assert_eq!(Utc.ymd(2014, 11, 28).and_hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(),
359 //! "070809");
360 //! ```
361 //!
362 //! There is no timezone-aware `Time` due to the lack of usefulness and also the complexity.
363 //!
364 //! `DateTime` has [`date`](./struct.DateTime.html#method.date) method
365 //! which returns a `Date` which represents its date component.
366 //! There is also a [`time`](./struct.DateTime.html#method.time) method,
367 //! which simply returns a naive local time described below.
368 //!
369 //! ### Naive date and time
370 //!
371 //! Chrono provides naive counterparts to `Date`, (non-existent) `Time` and `DateTime`
372 //! as [**`NaiveDate`**](./naive/struct.NaiveDate.html),
373 //! [**`NaiveTime`**](./naive/struct.NaiveTime.html) and
374 //! [**`NaiveDateTime`**](./naive/struct.NaiveDateTime.html) respectively.
375 //!
376 //! They have almost equivalent interfaces as their timezone-aware twins,
377 //! but are not associated to time zones obviously and can be quite low-level.
378 //! They are mostly useful for building blocks for higher-level types.
379 //!
380 //! Timezone-aware `DateTime` and `Date` types have two methods returning naive versions:
381 //! [`naive_local`](./struct.DateTime.html#method.naive_local) returns
382 //! a view to the naive local time,
383 //! and [`naive_utc`](./struct.DateTime.html#method.naive_utc) returns
384 //! a view to the naive UTC time.
385 //!
386 //! ## Limitations
387 //!
388 //! Only proleptic Gregorian calendar (i.e. extended to support older dates) is supported.
389 //! Be very careful if you really have to deal with pre-20C dates, they can be in Julian or others.
390 //!
391 //! Date types are limited in about +/- 262,000 years from the common epoch.
392 //! Time types are limited in the nanosecond accuracy.
393 //!
394 //! [Leap seconds are supported in the representation but
395 //! Chrono doesn't try to make use of them](./naive/struct.NaiveTime.html#leap-second-handling).
396 //! (The main reason is that leap seconds are not really predictable.)
397 //! Almost *every* operation over the possible leap seconds will ignore them.
398 //! Consider using `NaiveDateTime` with the implicit TAI (International Atomic Time) scale
399 //! if you want.
400 //!
401 //! Chrono inherently does not support an inaccurate or partial date and time representation.
402 //! Any operation that can be ambiguous will return `None` in such cases.
403 //! For example, "a month later" of 2014-01-30 is not well-defined
404 //! and consequently `Utc.ymd(2014, 1, 30).with_month(2)` returns `None`.
405 //!
406 //! Non ISO week handling is not yet supported.
407 //! For now you can use the [chrono_ext](https://crates.io/crates/chrono_ext)
408 //! crate ([sources](https://github.com/bcourtine/chrono-ext/)).
409 //!
410 //! Advanced time zone handling is not yet supported.
411 //! For now you can try the [Chrono-tz](https://github.com/chronotope/chrono-tz/) crate instead.
412
413 #![doc(html_root_url = "https://docs.rs/chrono/latest/")]
414 #![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507
415 #![deny(missing_docs)]
416 #![deny(missing_debug_implementations)]
417 #![deny(dead_code)]
418 // lints are added all the time, we test on 1.13
419 #![allow(unknown_lints)]
420 #![cfg_attr(not(any(feature = "std", test)), no_std)]
421 #![cfg_attr(feature = "cargo-clippy", allow(
422 renamed_and_removed_lints,
423 // The explicit 'static lifetimes are still needed for rustc 1.13-16
424 // backward compatibility, and this appeases clippy. If minimum rustc
425 // becomes 1.17, should be able to remove this, those 'static lifetimes,
426 // and use `static` in a lot of places `const` is used now.
427 redundant_static_lifetimes,
428 // Similarly, redundant_field_names lints on not using the
429 // field-init-shorthand, which was stabilized in rust 1.17.
430 redundant_field_names,
431 // Changing trivially_copy_pass_by_ref would require an incompatible version
432 // bump.
433 trivially_copy_pass_by_ref,
434 try_err,
435 // Currently deprecated, we use the separate implementation to add docs
436 // warning that putting a time in a hash table is probably a bad idea
437 derive_hash_xor_eq,
438 ))]
439
440 #[cfg(feature = "alloc")]
441 extern crate alloc;
442 #[cfg(all(feature = "std", not(feature = "alloc")))]
443 extern crate std as alloc;
444 #[cfg(any(feature = "std", test))]
445 extern crate std as core;
446
447 #[cfg(feature = "oldtime")]
448 extern crate time as oldtime;
449 #[cfg(not(feature = "oldtime"))]
450 mod oldtime;
451
452 #[cfg(feature = "clock")]
453 extern crate libc;
454 #[cfg(all(feature = "clock", windows))]
455 extern crate winapi;
456 #[cfg(all(
457 feature = "clock",
458 not(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))
459 ))]
460 mod sys;
461
462 extern crate num_integer;
463 extern crate num_traits;
464 #[cfg(feature = "rustc-serialize")]
465 extern crate rustc_serialize;
466 #[cfg(feature = "serde")]
467 extern crate serde as serdelib;
468 #[cfg(feature = "__doctest")]
469 #[cfg_attr(feature = "__doctest", cfg(doctest))]
470 #[macro_use]
471 extern crate doc_comment;
472 #[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
473 extern crate js_sys;
474 #[cfg(feature = "unstable-locales")]
475 extern crate pure_rust_locales;
476 #[cfg(feature = "bench")]
477 extern crate test;
478 #[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
479 extern crate wasm_bindgen;
480
481 #[cfg(feature = "__doctest")]
482 #[cfg_attr(feature = "__doctest", cfg(doctest))]
483 doctest!("../README.md");
484
485 // this reexport is to aid the transition and should not be in the prelude!
486 pub use oldtime::Duration;
487
488 pub use date::{Date, MAX_DATE, MIN_DATE};
489 #[cfg(feature = "rustc-serialize")]
490 pub use datetime::rustc_serialize::TsSeconds;
491 pub use datetime::{DateTime, SecondsFormat, MAX_DATETIME, MIN_DATETIME};
492 /// L10n locales.
493 #[cfg(feature = "unstable-locales")]
494 pub use format::Locale;
495 pub use format::{ParseError, ParseResult};
496 #[doc(no_inline)]
497 pub use naive::{IsoWeek, NaiveDate, NaiveDateTime, NaiveTime};
498 #[cfg(feature = "clock")]
499 #[doc(no_inline)]
500 pub use offset::Local;
501 #[doc(no_inline)]
502 pub use offset::{FixedOffset, LocalResult, Offset, TimeZone, Utc};
503 pub use round::{DurationRound, RoundingError, SubsecRound};
504
505 /// A convenience module appropriate for glob imports (`use chrono::prelude::*;`).
506 pub mod prelude {
507 #[doc(no_inline)]
508 pub use Date;
509 #[cfg(feature = "clock")]
510 #[doc(no_inline)]
511 pub use Local;
512 #[cfg(feature = "unstable-locales")]
513 #[doc(no_inline)]
514 pub use Locale;
515 #[doc(no_inline)]
516 pub use SubsecRound;
517 #[doc(no_inline)]
518 pub use {DateTime, SecondsFormat};
519 #[doc(no_inline)]
520 pub use {Datelike, Month, Timelike, Weekday};
521 #[doc(no_inline)]
522 pub use {FixedOffset, Utc};
523 #[doc(no_inline)]
524 pub use {NaiveDate, NaiveDateTime, NaiveTime};
525 #[doc(no_inline)]
526 pub use {Offset, TimeZone};
527 }
528
529 // useful throughout the codebase
530 macro_rules! try_opt {
531 ($e:expr) => {
532 match $e {
533 Some(v) => v,
534 None => return None,
535 }
536 };
537 }
538
539 mod div;
540 pub mod offset;
541 pub mod naive {
542 //! Date and time types unconcerned with timezones.
543 //!
544 //! They are primarily building blocks for other types
545 //! (e.g. [`TimeZone`](../offset/trait.TimeZone.html)),
546 //! but can be also used for the simpler date and time handling.
547
548 mod date;
549 mod datetime;
550 mod internals;
551 mod isoweek;
552 mod time;
553
554 pub use self::date::{NaiveDate, MAX_DATE, MIN_DATE};
555 #[cfg(feature = "rustc-serialize")]
556 #[allow(deprecated)]
557 pub use self::datetime::rustc_serialize::TsSeconds;
558 pub use self::datetime::{NaiveDateTime, MAX_DATETIME, MIN_DATETIME};
559 pub use self::isoweek::IsoWeek;
560 pub use self::time::NaiveTime;
561
562 #[cfg(feature = "__internal_bench")]
563 #[doc(hidden)]
564 pub use self::internals::YearFlags as __BenchYearFlags;
565
566 /// Serialization/Deserialization of naive types in alternate formats
567 ///
568 /// The various modules in here are intended to be used with serde's [`with`
569 /// annotation][1] to serialize as something other than the default [RFC
570 /// 3339][2] format.
571 ///
572 /// [1]: https://serde.rs/attributes.html#field-attributes
573 /// [2]: https://tools.ietf.org/html/rfc3339
574 #[cfg(feature = "serde")]
575 pub mod serde {
576 pub use super::datetime::serde::*;
577 }
578 }
579 mod date;
580 mod datetime;
581 pub mod format;
582 mod round;
583
584 #[cfg(feature = "__internal_bench")]
585 #[doc(hidden)]
586 pub use naive::__BenchYearFlags;
587
588 /// Serialization/Deserialization in alternate formats
589 ///
590 /// The various modules in here are intended to be used with serde's [`with`
591 /// annotation][1] to serialize as something other than the default [RFC
592 /// 3339][2] format.
593 ///
594 /// [1]: https://serde.rs/attributes.html#field-attributes
595 /// [2]: https://tools.ietf.org/html/rfc3339
596 #[cfg(feature = "serde")]
597 pub mod serde {
598 pub use super::datetime::serde::*;
599 }
600
601 // Until rust 1.18 there is no "pub(crate)" so to share this we need it in the root
602
603 #[cfg(feature = "serde")]
604 enum SerdeError<V: fmt::Display, D: fmt::Display> {
605 NonExistent { timestamp: V },
606 Ambiguous { timestamp: V, min: D, max: D },
607 }
608
609 /// Construct a [`SerdeError::NonExistent`]
610 #[cfg(feature = "serde")]
ne_timestamp<T: fmt::Display>(ts: T) -> SerdeError<T, u8>611 fn ne_timestamp<T: fmt::Display>(ts: T) -> SerdeError<T, u8> {
612 SerdeError::NonExistent::<T, u8> { timestamp: ts }
613 }
614
615 #[cfg(feature = "serde")]
616 impl<V: fmt::Display, D: fmt::Display> fmt::Debug for SerdeError<V, D> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result617 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
618 write!(f, "ChronoSerdeError({})", self)
619 }
620 }
621
622 // impl<V: fmt::Display, D: fmt::Debug> core::error::Error for SerdeError<V, D> {}
623 #[cfg(feature = "serde")]
624 impl<V: fmt::Display, D: fmt::Display> fmt::Display for SerdeError<V, D> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result625 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
626 match self {
627 &SerdeError::NonExistent { ref timestamp } => {
628 write!(f, "value is not a legal timestamp: {}", timestamp)
629 }
630 &SerdeError::Ambiguous { ref timestamp, ref min, ref max } => write!(
631 f,
632 "value is an ambiguous timestamp: {}, could be either of {}, {}",
633 timestamp, min, max
634 ),
635 }
636 }
637 }
638
639 /// The day of week.
640 ///
641 /// The order of the days of week depends on the context.
642 /// (This is why this type does *not* implement `PartialOrd` or `Ord` traits.)
643 /// One should prefer `*_from_monday` or `*_from_sunday` methods to get the correct result.
644 #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
645 #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
646 pub enum Weekday {
647 /// Monday.
648 Mon = 0,
649 /// Tuesday.
650 Tue = 1,
651 /// Wednesday.
652 Wed = 2,
653 /// Thursday.
654 Thu = 3,
655 /// Friday.
656 Fri = 4,
657 /// Saturday.
658 Sat = 5,
659 /// Sunday.
660 Sun = 6,
661 }
662
663 impl Weekday {
664 /// The next day in the week.
665 ///
666 /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
667 /// ----------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
668 /// `w.succ()`: | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun` | `Mon`
669 #[inline]
succ(&self) -> Weekday670 pub fn succ(&self) -> Weekday {
671 match *self {
672 Weekday::Mon => Weekday::Tue,
673 Weekday::Tue => Weekday::Wed,
674 Weekday::Wed => Weekday::Thu,
675 Weekday::Thu => Weekday::Fri,
676 Weekday::Fri => Weekday::Sat,
677 Weekday::Sat => Weekday::Sun,
678 Weekday::Sun => Weekday::Mon,
679 }
680 }
681
682 /// The previous day in the week.
683 ///
684 /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
685 /// ----------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
686 /// `w.pred()`: | `Sun` | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat`
687 #[inline]
pred(&self) -> Weekday688 pub fn pred(&self) -> Weekday {
689 match *self {
690 Weekday::Mon => Weekday::Sun,
691 Weekday::Tue => Weekday::Mon,
692 Weekday::Wed => Weekday::Tue,
693 Weekday::Thu => Weekday::Wed,
694 Weekday::Fri => Weekday::Thu,
695 Weekday::Sat => Weekday::Fri,
696 Weekday::Sun => Weekday::Sat,
697 }
698 }
699
700 /// Returns a day-of-week number starting from Monday = 1. (ISO 8601 weekday number)
701 ///
702 /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
703 /// ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
704 /// `w.number_from_monday()`: | 1 | 2 | 3 | 4 | 5 | 6 | 7
705 #[inline]
number_from_monday(&self) -> u32706 pub fn number_from_monday(&self) -> u32 {
707 match *self {
708 Weekday::Mon => 1,
709 Weekday::Tue => 2,
710 Weekday::Wed => 3,
711 Weekday::Thu => 4,
712 Weekday::Fri => 5,
713 Weekday::Sat => 6,
714 Weekday::Sun => 7,
715 }
716 }
717
718 /// Returns a day-of-week number starting from Sunday = 1.
719 ///
720 /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
721 /// ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
722 /// `w.number_from_sunday()`: | 2 | 3 | 4 | 5 | 6 | 7 | 1
723 #[inline]
number_from_sunday(&self) -> u32724 pub fn number_from_sunday(&self) -> u32 {
725 match *self {
726 Weekday::Mon => 2,
727 Weekday::Tue => 3,
728 Weekday::Wed => 4,
729 Weekday::Thu => 5,
730 Weekday::Fri => 6,
731 Weekday::Sat => 7,
732 Weekday::Sun => 1,
733 }
734 }
735
736 /// Returns a day-of-week number starting from Monday = 0.
737 ///
738 /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
739 /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
740 /// `w.num_days_from_monday()`: | 0 | 1 | 2 | 3 | 4 | 5 | 6
741 #[inline]
num_days_from_monday(&self) -> u32742 pub fn num_days_from_monday(&self) -> u32 {
743 match *self {
744 Weekday::Mon => 0,
745 Weekday::Tue => 1,
746 Weekday::Wed => 2,
747 Weekday::Thu => 3,
748 Weekday::Fri => 4,
749 Weekday::Sat => 5,
750 Weekday::Sun => 6,
751 }
752 }
753
754 /// Returns a day-of-week number starting from Sunday = 0.
755 ///
756 /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
757 /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
758 /// `w.num_days_from_sunday()`: | 1 | 2 | 3 | 4 | 5 | 6 | 0
759 #[inline]
num_days_from_sunday(&self) -> u32760 pub fn num_days_from_sunday(&self) -> u32 {
761 match *self {
762 Weekday::Mon => 1,
763 Weekday::Tue => 2,
764 Weekday::Wed => 3,
765 Weekday::Thu => 4,
766 Weekday::Fri => 5,
767 Weekday::Sat => 6,
768 Weekday::Sun => 0,
769 }
770 }
771 }
772
773 impl fmt::Display for Weekday {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result774 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
775 f.write_str(match *self {
776 Weekday::Mon => "Mon",
777 Weekday::Tue => "Tue",
778 Weekday::Wed => "Wed",
779 Weekday::Thu => "Thu",
780 Weekday::Fri => "Fri",
781 Weekday::Sat => "Sat",
782 Weekday::Sun => "Sun",
783 })
784 }
785 }
786
787 /// Any weekday can be represented as an integer from 0 to 6, which equals to
788 /// [`Weekday::num_days_from_monday`](#method.num_days_from_monday) in this implementation.
789 /// Do not heavily depend on this though; use explicit methods whenever possible.
790 impl num_traits::FromPrimitive for Weekday {
791 #[inline]
from_i64(n: i64) -> Option<Weekday>792 fn from_i64(n: i64) -> Option<Weekday> {
793 match n {
794 0 => Some(Weekday::Mon),
795 1 => Some(Weekday::Tue),
796 2 => Some(Weekday::Wed),
797 3 => Some(Weekday::Thu),
798 4 => Some(Weekday::Fri),
799 5 => Some(Weekday::Sat),
800 6 => Some(Weekday::Sun),
801 _ => None,
802 }
803 }
804
805 #[inline]
from_u64(n: u64) -> Option<Weekday>806 fn from_u64(n: u64) -> Option<Weekday> {
807 match n {
808 0 => Some(Weekday::Mon),
809 1 => Some(Weekday::Tue),
810 2 => Some(Weekday::Wed),
811 3 => Some(Weekday::Thu),
812 4 => Some(Weekday::Fri),
813 5 => Some(Weekday::Sat),
814 6 => Some(Weekday::Sun),
815 _ => None,
816 }
817 }
818 }
819
820 use core::fmt;
821
822 /// An error resulting from reading `Weekday` value with `FromStr`.
823 #[derive(Clone, PartialEq)]
824 pub struct ParseWeekdayError {
825 _dummy: (),
826 }
827
828 impl fmt::Debug for ParseWeekdayError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result829 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
830 write!(f, "ParseWeekdayError {{ .. }}")
831 }
832 }
833
834 // the actual `FromStr` implementation is in the `format` module to leverage the existing code
835
836 #[cfg(feature = "serde")]
837 mod weekday_serde {
838 use super::Weekday;
839 use core::fmt;
840 use serdelib::{de, ser};
841
842 impl ser::Serialize for Weekday {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,843 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
844 where
845 S: ser::Serializer,
846 {
847 serializer.collect_str(&self)
848 }
849 }
850
851 struct WeekdayVisitor;
852
853 impl<'de> de::Visitor<'de> for WeekdayVisitor {
854 type Value = Weekday;
855
expecting(&self, f: &mut fmt::Formatter) -> fmt::Result856 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
857 write!(f, "Weekday")
858 }
859
visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: de::Error,860 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
861 where
862 E: de::Error,
863 {
864 value.parse().map_err(|_| E::custom("short or long weekday names expected"))
865 }
866 }
867
868 impl<'de> de::Deserialize<'de> for Weekday {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,869 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
870 where
871 D: de::Deserializer<'de>,
872 {
873 deserializer.deserialize_str(WeekdayVisitor)
874 }
875 }
876
877 #[cfg(test)]
878 extern crate serde_json;
879
880 #[test]
test_serde_serialize()881 fn test_serde_serialize() {
882 use self::serde_json::to_string;
883 use Weekday::*;
884
885 let cases: Vec<(Weekday, &str)> = vec![
886 (Mon, "\"Mon\""),
887 (Tue, "\"Tue\""),
888 (Wed, "\"Wed\""),
889 (Thu, "\"Thu\""),
890 (Fri, "\"Fri\""),
891 (Sat, "\"Sat\""),
892 (Sun, "\"Sun\""),
893 ];
894
895 for (weekday, expected_str) in cases {
896 let string = to_string(&weekday).unwrap();
897 assert_eq!(string, expected_str);
898 }
899 }
900
901 #[test]
test_serde_deserialize()902 fn test_serde_deserialize() {
903 use self::serde_json::from_str;
904 use Weekday::*;
905
906 let cases: Vec<(&str, Weekday)> = vec![
907 ("\"mon\"", Mon),
908 ("\"MONDAY\"", Mon),
909 ("\"MonDay\"", Mon),
910 ("\"mOn\"", Mon),
911 ("\"tue\"", Tue),
912 ("\"tuesday\"", Tue),
913 ("\"wed\"", Wed),
914 ("\"wednesday\"", Wed),
915 ("\"thu\"", Thu),
916 ("\"thursday\"", Thu),
917 ("\"fri\"", Fri),
918 ("\"friday\"", Fri),
919 ("\"sat\"", Sat),
920 ("\"saturday\"", Sat),
921 ("\"sun\"", Sun),
922 ("\"sunday\"", Sun),
923 ];
924
925 for (str, expected_weekday) in cases {
926 let weekday = from_str::<Weekday>(str).unwrap();
927 assert_eq!(weekday, expected_weekday);
928 }
929
930 let errors: Vec<&str> =
931 vec!["\"not a weekday\"", "\"monDAYs\"", "\"mond\"", "mon", "\"thur\"", "\"thurs\""];
932
933 for str in errors {
934 from_str::<Weekday>(str).unwrap_err();
935 }
936 }
937 }
938
939 /// The month of the year.
940 ///
941 /// This enum is just a convenience implementation.
942 /// The month in dates created by DateLike objects does not return this enum.
943 ///
944 /// It is possible to convert from a date to a month independently
945 /// ```
946 /// # extern crate num_traits;
947 /// use num_traits::FromPrimitive;
948 /// use chrono::prelude::*;
949 /// let date = Utc.ymd(2019, 10, 28).and_hms(9, 10, 11);
950 /// // `2019-10-28T09:10:11Z`
951 /// let month = Month::from_u32(date.month());
952 /// assert_eq!(month, Some(Month::October))
953 /// ```
954 /// Or from a Month to an integer usable by dates
955 /// ```
956 /// # use chrono::prelude::*;
957 /// let month = Month::January;
958 /// let dt = Utc.ymd(2019, month.number_from_month(), 28).and_hms(9, 10, 11);
959 /// assert_eq!((dt.year(), dt.month(), dt.day()), (2019, 1, 28));
960 /// ```
961 /// Allows mapping from and to month, from 1-January to 12-December.
962 /// Can be Serialized/Deserialized with serde
963 // Actual implementation is zero-indexed, API intended as 1-indexed for more intuitive behavior.
964 #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
965 #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
966 pub enum Month {
967 /// January
968 January = 0,
969 /// February
970 February = 1,
971 /// March
972 March = 2,
973 /// April
974 April = 3,
975 /// May
976 May = 4,
977 /// June
978 June = 5,
979 /// July
980 July = 6,
981 /// August
982 August = 7,
983 /// September
984 September = 8,
985 /// October
986 October = 9,
987 /// November
988 November = 10,
989 /// December
990 December = 11,
991 }
992
993 impl Month {
994 /// The next month.
995 ///
996 /// `m`: | `January` | `February` | `...` | `December`
997 /// ----------- | --------- | ---------- | --- | ---------
998 /// `m.succ()`: | `February` | `March` | `...` | `January`
999 #[inline]
succ(&self) -> Month1000 pub fn succ(&self) -> Month {
1001 match *self {
1002 Month::January => Month::February,
1003 Month::February => Month::March,
1004 Month::March => Month::April,
1005 Month::April => Month::May,
1006 Month::May => Month::June,
1007 Month::June => Month::July,
1008 Month::July => Month::August,
1009 Month::August => Month::September,
1010 Month::September => Month::October,
1011 Month::October => Month::November,
1012 Month::November => Month::December,
1013 Month::December => Month::January,
1014 }
1015 }
1016
1017 /// The previous month.
1018 ///
1019 /// `m`: | `January` | `February` | `...` | `December`
1020 /// ----------- | --------- | ---------- | --- | ---------
1021 /// `m.succ()`: | `December` | `January` | `...` | `November`
1022 #[inline]
pred(&self) -> Month1023 pub fn pred(&self) -> Month {
1024 match *self {
1025 Month::January => Month::December,
1026 Month::February => Month::January,
1027 Month::March => Month::February,
1028 Month::April => Month::March,
1029 Month::May => Month::April,
1030 Month::June => Month::May,
1031 Month::July => Month::June,
1032 Month::August => Month::July,
1033 Month::September => Month::August,
1034 Month::October => Month::September,
1035 Month::November => Month::October,
1036 Month::December => Month::November,
1037 }
1038 }
1039
1040 /// Returns a month-of-year number starting from January = 1.
1041 ///
1042 /// `m`: | `January` | `February` | `...` | `December`
1043 /// -------------------------| --------- | ---------- | --- | -----
1044 /// `m.number_from_month()`: | 1 | 2 | `...` | 12
1045 #[inline]
number_from_month(&self) -> u321046 pub fn number_from_month(&self) -> u32 {
1047 match *self {
1048 Month::January => 1,
1049 Month::February => 2,
1050 Month::March => 3,
1051 Month::April => 4,
1052 Month::May => 5,
1053 Month::June => 6,
1054 Month::July => 7,
1055 Month::August => 8,
1056 Month::September => 9,
1057 Month::October => 10,
1058 Month::November => 11,
1059 Month::December => 12,
1060 }
1061 }
1062
1063 /// Get the name of the month
1064 ///
1065 /// ```
1066 /// use chrono::Month;
1067 ///
1068 /// assert_eq!(Month::January.name(), "January")
1069 /// ```
name(&self) -> &'static str1070 pub fn name(&self) -> &'static str {
1071 match *self {
1072 Month::January => "January",
1073 Month::February => "February",
1074 Month::March => "March",
1075 Month::April => "April",
1076 Month::May => "May",
1077 Month::June => "June",
1078 Month::July => "July",
1079 Month::August => "August",
1080 Month::September => "September",
1081 Month::October => "October",
1082 Month::November => "November",
1083 Month::December => "December",
1084 }
1085 }
1086 }
1087
1088 impl num_traits::FromPrimitive for Month {
1089 /// Returns an Option<Month> from a i64, assuming a 1-index, January = 1.
1090 ///
1091 /// `Month::from_i64(n: i64)`: | `1` | `2` | ... | `12`
1092 /// ---------------------------| -------------------- | --------------------- | ... | -----
1093 /// ``: | Some(Month::January) | Some(Month::February) | ... | Some(Month::December)
1094
1095 #[inline]
from_u64(n: u64) -> Option<Month>1096 fn from_u64(n: u64) -> Option<Month> {
1097 Self::from_u32(n as u32)
1098 }
1099
1100 #[inline]
from_i64(n: i64) -> Option<Month>1101 fn from_i64(n: i64) -> Option<Month> {
1102 Self::from_u32(n as u32)
1103 }
1104
1105 #[inline]
from_u32(n: u32) -> Option<Month>1106 fn from_u32(n: u32) -> Option<Month> {
1107 match n {
1108 1 => Some(Month::January),
1109 2 => Some(Month::February),
1110 3 => Some(Month::March),
1111 4 => Some(Month::April),
1112 5 => Some(Month::May),
1113 6 => Some(Month::June),
1114 7 => Some(Month::July),
1115 8 => Some(Month::August),
1116 9 => Some(Month::September),
1117 10 => Some(Month::October),
1118 11 => Some(Month::November),
1119 12 => Some(Month::December),
1120 _ => None,
1121 }
1122 }
1123 }
1124
1125 /// An error resulting from reading `<Month>` value with `FromStr`.
1126 #[derive(Clone, PartialEq)]
1127 pub struct ParseMonthError {
1128 _dummy: (),
1129 }
1130
1131 impl fmt::Debug for ParseMonthError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1133 write!(f, "ParseMonthError {{ .. }}")
1134 }
1135 }
1136
1137 #[cfg(feature = "serde")]
1138 mod month_serde {
1139 use super::Month;
1140 use serdelib::{de, ser};
1141
1142 use core::fmt;
1143
1144 impl ser::Serialize for Month {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,1145 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1146 where
1147 S: ser::Serializer,
1148 {
1149 serializer.collect_str(self.name())
1150 }
1151 }
1152
1153 struct MonthVisitor;
1154
1155 impl<'de> de::Visitor<'de> for MonthVisitor {
1156 type Value = Month;
1157
expecting(&self, f: &mut fmt::Formatter) -> fmt::Result1158 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1159 write!(f, "Month")
1160 }
1161
visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: de::Error,1162 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1163 where
1164 E: de::Error,
1165 {
1166 value.parse().map_err(|_| E::custom("short (3-letter) or full month names expected"))
1167 }
1168 }
1169
1170 impl<'de> de::Deserialize<'de> for Month {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,1171 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1172 where
1173 D: de::Deserializer<'de>,
1174 {
1175 deserializer.deserialize_str(MonthVisitor)
1176 }
1177 }
1178
1179 #[cfg(test)]
1180 extern crate serde_json;
1181
1182 #[test]
test_serde_serialize()1183 fn test_serde_serialize() {
1184 use self::serde_json::to_string;
1185 use Month::*;
1186
1187 let cases: Vec<(Month, &str)> = vec![
1188 (January, "\"January\""),
1189 (February, "\"February\""),
1190 (March, "\"March\""),
1191 (April, "\"April\""),
1192 (May, "\"May\""),
1193 (June, "\"June\""),
1194 (July, "\"July\""),
1195 (August, "\"August\""),
1196 (September, "\"September\""),
1197 (October, "\"October\""),
1198 (November, "\"November\""),
1199 (December, "\"December\""),
1200 ];
1201
1202 for (month, expected_str) in cases {
1203 let string = to_string(&month).unwrap();
1204 assert_eq!(string, expected_str);
1205 }
1206 }
1207
1208 #[test]
test_serde_deserialize()1209 fn test_serde_deserialize() {
1210 use self::serde_json::from_str;
1211 use Month::*;
1212
1213 let cases: Vec<(&str, Month)> = vec![
1214 ("\"january\"", January),
1215 ("\"jan\"", January),
1216 ("\"FeB\"", February),
1217 ("\"MAR\"", March),
1218 ("\"mar\"", March),
1219 ("\"april\"", April),
1220 ("\"may\"", May),
1221 ("\"june\"", June),
1222 ("\"JULY\"", July),
1223 ("\"august\"", August),
1224 ("\"september\"", September),
1225 ("\"October\"", October),
1226 ("\"November\"", November),
1227 ("\"DECEmbEr\"", December),
1228 ];
1229
1230 for (string, expected_month) in cases {
1231 let month = from_str::<Month>(string).unwrap();
1232 assert_eq!(month, expected_month);
1233 }
1234
1235 let errors: Vec<&str> =
1236 vec!["\"not a month\"", "\"ja\"", "\"Dece\"", "Dec", "\"Augustin\""];
1237
1238 for string in errors {
1239 from_str::<Month>(string).unwrap_err();
1240 }
1241 }
1242 }
1243
1244 /// The common set of methods for date component.
1245 pub trait Datelike: Sized {
1246 /// Returns the year number in the [calendar date](./naive/struct.NaiveDate.html#calendar-date).
year(&self) -> i321247 fn year(&self) -> i32;
1248
1249 /// Returns the absolute year number starting from 1 with a boolean flag,
1250 /// which is false when the year predates the epoch (BCE/BC) and true otherwise (CE/AD).
1251 #[inline]
year_ce(&self) -> (bool, u32)1252 fn year_ce(&self) -> (bool, u32) {
1253 let year = self.year();
1254 if year < 1 {
1255 (false, (1 - year) as u32)
1256 } else {
1257 (true, year as u32)
1258 }
1259 }
1260
1261 /// Returns the month number starting from 1.
1262 ///
1263 /// The return value ranges from 1 to 12.
month(&self) -> u321264 fn month(&self) -> u32;
1265
1266 /// Returns the month number starting from 0.
1267 ///
1268 /// The return value ranges from 0 to 11.
month0(&self) -> u321269 fn month0(&self) -> u32;
1270
1271 /// Returns the day of month starting from 1.
1272 ///
1273 /// The return value ranges from 1 to 31. (The last day of month differs by months.)
day(&self) -> u321274 fn day(&self) -> u32;
1275
1276 /// Returns the day of month starting from 0.
1277 ///
1278 /// The return value ranges from 0 to 30. (The last day of month differs by months.)
day0(&self) -> u321279 fn day0(&self) -> u32;
1280
1281 /// Returns the day of year starting from 1.
1282 ///
1283 /// The return value ranges from 1 to 366. (The last day of year differs by years.)
ordinal(&self) -> u321284 fn ordinal(&self) -> u32;
1285
1286 /// Returns the day of year starting from 0.
1287 ///
1288 /// The return value ranges from 0 to 365. (The last day of year differs by years.)
ordinal0(&self) -> u321289 fn ordinal0(&self) -> u32;
1290
1291 /// Returns the day of week.
weekday(&self) -> Weekday1292 fn weekday(&self) -> Weekday;
1293
1294 /// Returns the ISO week.
iso_week(&self) -> IsoWeek1295 fn iso_week(&self) -> IsoWeek;
1296
1297 /// Makes a new value with the year number changed.
1298 ///
1299 /// Returns `None` when the resulting value would be invalid.
with_year(&self, year: i32) -> Option<Self>1300 fn with_year(&self, year: i32) -> Option<Self>;
1301
1302 /// Makes a new value with the month number (starting from 1) changed.
1303 ///
1304 /// Returns `None` when the resulting value would be invalid.
with_month(&self, month: u32) -> Option<Self>1305 fn with_month(&self, month: u32) -> Option<Self>;
1306
1307 /// Makes a new value with the month number (starting from 0) changed.
1308 ///
1309 /// Returns `None` when the resulting value would be invalid.
with_month0(&self, month0: u32) -> Option<Self>1310 fn with_month0(&self, month0: u32) -> Option<Self>;
1311
1312 /// Makes a new value with the day of month (starting from 1) changed.
1313 ///
1314 /// Returns `None` when the resulting value would be invalid.
with_day(&self, day: u32) -> Option<Self>1315 fn with_day(&self, day: u32) -> Option<Self>;
1316
1317 /// Makes a new value with the day of month (starting from 0) changed.
1318 ///
1319 /// Returns `None` when the resulting value would be invalid.
with_day0(&self, day0: u32) -> Option<Self>1320 fn with_day0(&self, day0: u32) -> Option<Self>;
1321
1322 /// Makes a new value with the day of year (starting from 1) changed.
1323 ///
1324 /// Returns `None` when the resulting value would be invalid.
with_ordinal(&self, ordinal: u32) -> Option<Self>1325 fn with_ordinal(&self, ordinal: u32) -> Option<Self>;
1326
1327 /// Makes a new value with the day of year (starting from 0) changed.
1328 ///
1329 /// Returns `None` when the resulting value would be invalid.
with_ordinal0(&self, ordinal0: u32) -> Option<Self>1330 fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;
1331
1332 /// Counts the days in the proleptic Gregorian calendar, with January 1, Year 1 (CE) as day 1.
1333 ///
1334 /// # Examples
1335 ///
1336 /// ```
1337 /// use chrono::{NaiveDate, Datelike};
1338 ///
1339 /// assert_eq!(NaiveDate::from_ymd(1970, 1, 1).num_days_from_ce(), 719_163);
1340 /// assert_eq!(NaiveDate::from_ymd(2, 1, 1).num_days_from_ce(), 366);
1341 /// assert_eq!(NaiveDate::from_ymd(1, 1, 1).num_days_from_ce(), 1);
1342 /// assert_eq!(NaiveDate::from_ymd(0, 1, 1).num_days_from_ce(), -365);
1343 /// ```
num_days_from_ce(&self) -> i321344 fn num_days_from_ce(&self) -> i32 {
1345 // See test_num_days_from_ce_against_alternative_impl below for a more straightforward
1346 // implementation.
1347
1348 // we know this wouldn't overflow since year is limited to 1/2^13 of i32's full range.
1349 let mut year = self.year() - 1;
1350 let mut ndays = 0;
1351 if year < 0 {
1352 let excess = 1 + (-year) / 400;
1353 year += excess * 400;
1354 ndays -= excess * 146_097;
1355 }
1356 let div_100 = year / 100;
1357 ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
1358 ndays + self.ordinal() as i32
1359 }
1360 }
1361
1362 /// The common set of methods for time component.
1363 pub trait Timelike: Sized {
1364 /// Returns the hour number from 0 to 23.
hour(&self) -> u321365 fn hour(&self) -> u32;
1366
1367 /// Returns the hour number from 1 to 12 with a boolean flag,
1368 /// which is false for AM and true for PM.
1369 #[inline]
hour12(&self) -> (bool, u32)1370 fn hour12(&self) -> (bool, u32) {
1371 let hour = self.hour();
1372 let mut hour12 = hour % 12;
1373 if hour12 == 0 {
1374 hour12 = 12;
1375 }
1376 (hour >= 12, hour12)
1377 }
1378
1379 /// Returns the minute number from 0 to 59.
minute(&self) -> u321380 fn minute(&self) -> u32;
1381
1382 /// Returns the second number from 0 to 59.
second(&self) -> u321383 fn second(&self) -> u32;
1384
1385 /// Returns the number of nanoseconds since the whole non-leap second.
1386 /// The range from 1,000,000,000 to 1,999,999,999 represents
1387 /// the [leap second](./naive/struct.NaiveTime.html#leap-second-handling).
nanosecond(&self) -> u321388 fn nanosecond(&self) -> u32;
1389
1390 /// Makes a new value with the hour number changed.
1391 ///
1392 /// Returns `None` when the resulting value would be invalid.
with_hour(&self, hour: u32) -> Option<Self>1393 fn with_hour(&self, hour: u32) -> Option<Self>;
1394
1395 /// Makes a new value with the minute number changed.
1396 ///
1397 /// Returns `None` when the resulting value would be invalid.
with_minute(&self, min: u32) -> Option<Self>1398 fn with_minute(&self, min: u32) -> Option<Self>;
1399
1400 /// Makes a new value with the second number changed.
1401 ///
1402 /// Returns `None` when the resulting value would be invalid.
1403 /// As with the [`second`](#tymethod.second) method,
1404 /// the input range is restricted to 0 through 59.
with_second(&self, sec: u32) -> Option<Self>1405 fn with_second(&self, sec: u32) -> Option<Self>;
1406
1407 /// Makes a new value with nanoseconds since the whole non-leap second changed.
1408 ///
1409 /// Returns `None` when the resulting value would be invalid.
1410 /// As with the [`nanosecond`](#tymethod.nanosecond) method,
1411 /// the input range can exceed 1,000,000,000 for leap seconds.
with_nanosecond(&self, nano: u32) -> Option<Self>1412 fn with_nanosecond(&self, nano: u32) -> Option<Self>;
1413
1414 /// Returns the number of non-leap seconds past the last midnight.
1415 #[inline]
num_seconds_from_midnight(&self) -> u321416 fn num_seconds_from_midnight(&self) -> u32 {
1417 self.hour() * 3600 + self.minute() * 60 + self.second()
1418 }
1419 }
1420
1421 #[cfg(test)]
1422 extern crate num_iter;
1423
1424 mod test {
1425 #[allow(unused_imports)]
1426 use super::*;
1427
1428 #[test]
test_readme_doomsday()1429 fn test_readme_doomsday() {
1430 use num_iter::range_inclusive;
1431
1432 for y in range_inclusive(naive::MIN_DATE.year(), naive::MAX_DATE.year()) {
1433 // even months
1434 let d4 = NaiveDate::from_ymd(y, 4, 4);
1435 let d6 = NaiveDate::from_ymd(y, 6, 6);
1436 let d8 = NaiveDate::from_ymd(y, 8, 8);
1437 let d10 = NaiveDate::from_ymd(y, 10, 10);
1438 let d12 = NaiveDate::from_ymd(y, 12, 12);
1439
1440 // nine to five, seven-eleven
1441 let d59 = NaiveDate::from_ymd(y, 5, 9);
1442 let d95 = NaiveDate::from_ymd(y, 9, 5);
1443 let d711 = NaiveDate::from_ymd(y, 7, 11);
1444 let d117 = NaiveDate::from_ymd(y, 11, 7);
1445
1446 // "March 0"
1447 let d30 = NaiveDate::from_ymd(y, 3, 1).pred();
1448
1449 let weekday = d30.weekday();
1450 let other_dates = [d4, d6, d8, d10, d12, d59, d95, d711, d117];
1451 assert!(other_dates.iter().all(|d| d.weekday() == weekday));
1452 }
1453 }
1454
1455 #[test]
test_month_enum_primitive_parse()1456 fn test_month_enum_primitive_parse() {
1457 use num_traits::FromPrimitive;
1458
1459 let jan_opt = Month::from_u32(1);
1460 let feb_opt = Month::from_u64(2);
1461 let dec_opt = Month::from_i64(12);
1462 let no_month = Month::from_u32(13);
1463 assert_eq!(jan_opt, Some(Month::January));
1464 assert_eq!(feb_opt, Some(Month::February));
1465 assert_eq!(dec_opt, Some(Month::December));
1466 assert_eq!(no_month, None);
1467
1468 let date = Utc.ymd(2019, 10, 28).and_hms(9, 10, 11);
1469 assert_eq!(Month::from_u32(date.month()), Some(Month::October));
1470
1471 let month = Month::January;
1472 let dt = Utc.ymd(2019, month.number_from_month(), 28).and_hms(9, 10, 11);
1473 assert_eq!((dt.year(), dt.month(), dt.day()), (2019, 1, 28));
1474 }
1475 }
1476
1477 /// Tests `Datelike::num_days_from_ce` against an alternative implementation.
1478 ///
1479 /// The alternative implementation is not as short as the current one but it is simpler to
1480 /// understand, with less unexplained magic constants.
1481 #[test]
test_num_days_from_ce_against_alternative_impl()1482 fn test_num_days_from_ce_against_alternative_impl() {
1483 /// Returns the number of multiples of `div` in the range `start..end`.
1484 ///
1485 /// If the range `start..end` is back-to-front, i.e. `start` is greater than `end`, the
1486 /// behaviour is defined by the following equation:
1487 /// `in_between(start, end, div) == - in_between(end, start, div)`.
1488 ///
1489 /// When `div` is 1, this is equivalent to `end - start`, i.e. the length of `start..end`.
1490 ///
1491 /// # Panics
1492 ///
1493 /// Panics if `div` is not positive.
1494 fn in_between(start: i32, end: i32, div: i32) -> i32 {
1495 assert!(div > 0, "in_between: nonpositive div = {}", div);
1496 let start = (start.div_euclid(div), start.rem_euclid(div));
1497 let end = (end.div_euclid(div), end.rem_euclid(div));
1498 // The lowest multiple of `div` greater than or equal to `start`, divided.
1499 let start = start.0 + (start.1 != 0) as i32;
1500 // The lowest multiple of `div` greater than or equal to `end`, divided.
1501 let end = end.0 + (end.1 != 0) as i32;
1502 end - start
1503 }
1504
1505 /// Alternative implementation to `Datelike::num_days_from_ce`
1506 fn num_days_from_ce<Date: Datelike>(date: &Date) -> i32 {
1507 let year = date.year();
1508 let diff = move |div| in_between(1, year, div);
1509 // 365 days a year, one more in leap years. In the gregorian calendar, leap years are all
1510 // the multiples of 4 except multiples of 100 but including multiples of 400.
1511 date.ordinal() as i32 + 365 * diff(1) + diff(4) - diff(100) + diff(400)
1512 }
1513
1514 use num_iter::range_inclusive;
1515
1516 for year in range_inclusive(naive::MIN_DATE.year(), naive::MAX_DATE.year()) {
1517 let jan1_year = NaiveDate::from_ymd(year, 1, 1);
1518 assert_eq!(
1519 jan1_year.num_days_from_ce(),
1520 num_days_from_ce(&jan1_year),
1521 "on {:?}",
1522 jan1_year
1523 );
1524 let mid_year = jan1_year + Duration::days(133);
1525 assert_eq!(mid_year.num_days_from_ce(), num_days_from_ce(&mid_year), "on {:?}", mid_year);
1526 }
1527 }
1528
1529 #[test]
test_month_enum_succ_pred()1530 fn test_month_enum_succ_pred() {
1531 assert_eq!(Month::January.succ(), Month::February);
1532 assert_eq!(Month::December.succ(), Month::January);
1533 assert_eq!(Month::January.pred(), Month::December);
1534 assert_eq!(Month::February.pred(), Month::January);
1535 }
1536