1 [Chrono][docsrs]: Date and Time for Rust
2 ========================================
4 [![Chrono GitHub Actions][gh-image]][gh-checks]
5 [![Chrono on crates.io][cratesio-image]][cratesio]
6 [![Chrono on docs.rs][docsrs-image]][docsrs]
7 [![Join the chat at https://gitter.im/chrono-rs/chrono][gitter-image]][gitter]
9 [gh-image]: https://github.com/chronotope/chrono/workflows/test/badge.svg
10 [gh-checks]: https://github.com/chronotope/chrono/actions?query=workflow%3Atest
11 [cratesio-image]: https://img.shields.io/crates/v/chrono.svg
12 [cratesio]: https://crates.io/crates/chrono
13 [docsrs-image]: https://docs.rs/chrono/badge.svg
14 [docsrs]: https://docs.rs/chrono
15 [gitter-image]: https://badges.gitter.im/chrono-rs/chrono.svg
16 [gitter]: https://gitter.im/chrono-rs/chrono
18 It aims to be a feature-complete superset of
19 the [time](https://github.com/rust-lang-deprecated/time) library.
22 * Chrono strictly adheres to ISO 8601.
23 * Chrono is timezone-aware by default, with separate timezone-naive types.
24 * Chrono is space-optimal and (while not being the primary goal) reasonably efficient.
26 There were several previous attempts to bring a good date and time library to Rust,
27 which Chrono builds upon and should acknowledge:
29 * [Initial research on
30 the wiki](https://github.com/rust-lang/rust-wiki-backup/blob/master/Lib-datetime.md)
31 * Dietrich Epp's [datetime-rs](https://github.com/depp/datetime-rs)
32 * Luis de Bethencourt's [rust-datetime](https://github.com/luisbg/rust-datetime)
34 Any significant changes to Chrono are documented in
35 the [`CHANGELOG.md`](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) file.
40 Put this in your `Cargo.toml`:
49 Chrono supports various runtime environments and operating systems, and has
50 several features that may be enabled or disabled.
54 - `alloc`: Enable features that depend on allocation (primarily string formatting)
55 - `std`: Enables functionality that depends on the standard library. This
56 is a superset of `alloc` and adds interoperation with standard library types
58 - `clock`: enables reading the system time (`now`), independent of whether
59 `std::time::SystemTime` is present, depends on having a libc.
63 - `wasmbind`: Enable integration with [wasm-bindgen][] and its `js-sys` project
64 - [`serde`][]: Enable serialization/deserialization via serde.
65 - `unstable-locales`: Enable localization. This adds various methods with a
66 `_localized` suffix. The implementation and API may change or even be
67 removed in a patch release. Feedback welcome.
69 [`serde`]: https://github.com/serde-rs/serde
70 [wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen
72 See the [cargo docs][] for examples of specifying features.
74 [cargo docs]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#choosing-features
80 Chrono currently uses its own [`Duration`] type to represent the magnitude
81 of a time span. Since this has the same name as the newer, standard type for
82 duration, the reference will refer this type as `OldDuration`.
84 Note that this is an "accurate" duration represented as seconds and
85 nanoseconds and does not represent "nominal" components such as days or
88 When the `oldtime` feature is enabled, [`Duration`] is an alias for the
89 [`time::Duration`](https://docs.rs/time/0.1.40/time/struct.Duration.html)
90 type from v0.1 of the time crate. time v0.1 is deprecated, so new code
91 should disable the `oldtime` feature and use the `chrono::Duration` type
92 instead. The `oldtime` feature is enabled by default for backwards
93 compatibility, but future versions of Chrono are likely to remove the
96 Chrono does not yet natively support
97 the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type,
98 but it will be supported in the future.
99 Meanwhile you can convert between two types with
100 [`Duration::from_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.from_std)
102 [`Duration::to_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.to_std)
108 [**`DateTime`**](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html)
109 type to represent a date and a time in a timezone.
111 For more abstract moment-in-time tracking such as internal timekeeping
112 that is unconcerned with timezones, consider
113 [`time::SystemTime`](https://doc.rust-lang.org/std/time/struct.SystemTime.html),
114 which tracks your system clock, or
115 [`time::Instant`](https://doc.rust-lang.org/std/time/struct.Instant.html), which
116 is an opaque but monotonically-increasing representation of a moment in time.
118 `DateTime` is timezone-aware and must be constructed from
119 the [**`TimeZone`**](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html) object,
120 which defines how the local date is converted to and back from the UTC date.
121 There are three well-known `TimeZone` implementations:
123 * [**`Utc`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html) specifies the UTC time zone. It is most efficient.
125 * [**`Local`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html) specifies the system local time zone.
127 * [**`FixedOffset`**](https://docs.rs/chrono/0.4/chrono/offset/struct.FixedOffset.html) specifies
128 an arbitrary, fixed time zone such as UTC+09:00 or UTC-10:30.
129 This often results from the parsed textual date and time.
130 Since it stores the most information and does not depend on the system environment,
131 you would want to normalize other `TimeZone`s into this type.
133 `DateTime`s with different `TimeZone` types are distinct and do not mix,
134 but can be converted to each other using
135 the [`DateTime::with_timezone`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.with_timezone) method.
137 You can get the current date and time in the UTC time zone
138 ([`Utc::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html#method.now))
139 or in the local time zone
140 ([`Local::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html#method.now)).
143 use chrono::prelude::*;
145 let utc: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
146 let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
149 Alternatively, you can create your own date and time.
150 This is a bit verbose due to Rust's lack of function and method overloading,
151 but in turn we get a rich combination of initialization methods.
154 use chrono::prelude::*;
155 use chrono::offset::LocalResult;
157 let dt = Utc.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z`
158 // July 8 is 188th day of the year 2014 (`o` for "ordinal")
159 assert_eq!(dt, Utc.yo(2014, 189).and_hms(9, 10, 11));
160 // July 8 is Tuesday in ISO week 28 of the year 2014.
161 assert_eq!(dt, Utc.isoywd(2014, 28, Weekday::Tue).and_hms(9, 10, 11));
163 let dt = Utc.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); // `2014-07-08T09:10:11.012Z`
164 assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_micro(9, 10, 11, 12_000));
165 assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_nano(9, 10, 11, 12_000_000));
167 // dynamic verification
168 assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(21, 15, 33),
169 LocalResult::Single(Utc.ymd(2014, 7, 8).and_hms(21, 15, 33)));
170 assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None);
171 assert_eq!(Utc.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None);
173 // other time zone objects can be used to construct a local datetime.
174 // obviously, `local_dt` is normally different from `dt`, but `fixed_dt` should be identical.
175 let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12);
176 let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12);
177 assert_eq!(dt, fixed_dt);
180 Various properties are available to the date and time, and can be altered individually.
181 Most of them are defined in the traits [`Datelike`](https://docs.rs/chrono/0.4/chrono/trait.Datelike.html) and
182 [`Timelike`](https://docs.rs/chrono/0.4/chrono/trait.Timelike.html) which you should `use` before.
183 Addition and subtraction is also supported.
184 The following illustrates most supported operations to the date and time:
188 use chrono::prelude::*;
189 use chrono::Duration;
191 // assume this returned `2014-11-28T21:45:59.324310806+09:00`:
192 let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806);
194 // property accessors
195 assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28));
196 assert_eq!((dt.month0(), dt.day0()), (10, 27)); // for unfortunate souls
197 assert_eq!((dt.hour(), dt.minute(), dt.second()), (21, 45, 59));
198 assert_eq!(dt.weekday(), Weekday::Fri);
199 assert_eq!(dt.weekday().number_from_monday(), 5); // Mon=1, ..., Sun=7
200 assert_eq!(dt.ordinal(), 332); // the day of year
201 assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1
203 // time zone accessor and manipulation
204 assert_eq!(dt.offset().fix().local_minus_utc(), 9 * 3600);
205 assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600));
206 assert_eq!(dt.with_timezone(&Utc), Utc.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806));
208 // a sample of property manipulations (validates dynamically)
209 assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday
210 assert_eq!(dt.with_day(32), None);
211 assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE
213 // arithmetic operations
214 let dt1 = Utc.ymd(2014, 11, 14).and_hms(8, 9, 10);
215 let dt2 = Utc.ymd(2014, 11, 14).and_hms(10, 9, 8);
216 assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2));
217 assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2));
218 assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000),
219 Utc.ymd(2001, 9, 9).and_hms(1, 46, 40));
220 assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000),
221 Utc.ymd(1938, 4, 24).and_hms(22, 13, 20));
224 ### Formatting and Parsing
226 Formatting is done via the [`format`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.format) method,
227 which format is equivalent to the familiar `strftime` format.
229 See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers)
230 documentation for full syntax and list of specifiers.
232 The default `to_string` method and `{:?}` specifier also give a reasonable representation.
233 Chrono also provides [`to_rfc2822`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.to_rfc2822) and
234 [`to_rfc3339`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.to_rfc3339) methods
235 for well-known formats.
237 Chrono now also provides date formatting in almost any language without the
238 help of an additional C library. This functionality is under the feature
242 chrono { version = "0.4", features = ["unstable-locales"]
245 The `unstable-locales` feature requires and implies at least the `alloc` feature.
248 use chrono::prelude::*;
250 let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);
251 assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
252 assert_eq!(dt.format("%a %b %e %T %Y").to_string(), "Fri Nov 28 12:00:09 2014");
253 assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), "vendredi 28 novembre 2014, 12:00:09");
254 assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string());
256 assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC");
257 assert_eq!(dt.to_rfc2822(), "Fri, 28 Nov 2014 12:00:09 +0000");
258 assert_eq!(dt.to_rfc3339(), "2014-11-28T12:00:09+00:00");
259 assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
261 // Note that milli/nanoseconds are only printed if they are non-zero
262 let dt_nano = Utc.ymd(2014, 11, 28).and_hms_nano(12, 0, 9, 1);
263 assert_eq!(format!("{:?}", dt_nano), "2014-11-28T12:00:09.000000001Z");
266 Parsing can be done with three methods:
268 1. The standard [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait
269 (and [`parse`](https://doc.rust-lang.org/std/primitive.str.html#method.parse) method
270 on a string) can be used for parsing `DateTime<FixedOffset>`, `DateTime<Utc>` and
271 `DateTime<Local>` values. This parses what the `{:?}`
272 ([`std::fmt::Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html))
273 format specifier prints, and requires the offset to be present.
275 2. [`DateTime::parse_from_str`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_str) parses
276 a date and time with offsets and returns `DateTime<FixedOffset>`.
277 This should be used when the offset is a part of input and the caller cannot guess that.
278 It *cannot* be used when the offset can be missing.
279 [`DateTime::parse_from_rfc2822`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_rfc2822)
281 [`DateTime::parse_from_rfc3339`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_rfc3339)
282 are similar but for well-known formats.
284 3. [`Offset::datetime_from_str`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.datetime_from_str) is
285 similar but returns `DateTime` of given offset.
286 When the explicit offset is missing from the input, it simply uses given offset.
287 It issues an error when the input contains an explicit offset different
288 from the current offset.
290 More detailed control over the parsing process is available via
291 [`format`](https://docs.rs/chrono/0.4/chrono/format/index.html) module.
294 use chrono::prelude::*;
296 let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);
297 let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600));
300 assert_eq!("2014-11-28T12:00:09Z".parse::<DateTime<Utc>>(), Ok(dt.clone()));
301 assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<Utc>>(), Ok(dt.clone()));
302 assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<FixedOffset>>(), Ok(fixed_dt.clone()));
305 assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z"),
306 Ok(fixed_dt.clone()));
307 assert_eq!(DateTime::parse_from_rfc2822("Fri, 28 Nov 2014 21:00:09 +0900"),
308 Ok(fixed_dt.clone()));
309 assert_eq!(DateTime::parse_from_rfc3339("2014-11-28T21:00:09+09:00"), Ok(fixed_dt.clone()));
312 assert_eq!(Utc.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone()));
313 assert_eq!(Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone()));
315 // oops, the year is missing!
316 assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err());
317 // oops, the format string does not include the year at all!
318 assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T").is_err());
319 // oops, the weekday is incorrect!
320 assert!(Utc.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err());
323 Again : See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers)
324 documentation for full syntax and list of specifiers.
326 ### Conversion from and to EPOCH timestamps
328 Use [`Utc.timestamp(seconds, nanoseconds)`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.timestamp)
329 to construct a [`DateTime<Utc>`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html) from a UNIX timestamp
330 (seconds, nanoseconds that passed since January 1st 1970).
332 Use [`DateTime.timestamp`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp) to get the timestamp (in seconds)
333 from a [`DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html). Additionally, you can use
334 [`DateTime.timestamp_subsec_nanos`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp_subsec_nanos)
335 to get the number of additional number of nanoseconds.
338 // We need the trait in scope to use Utc::timestamp().
339 use chrono::{DateTime, TimeZone, Utc};
341 // Construct a datetime from epoch:
342 let dt = Utc.timestamp(1_500_000_000, 0);
343 assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000");
345 // Get epoch value from a datetime:
346 let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap();
347 assert_eq!(dt.timestamp(), 1_500_000_000);
352 Chrono also provides an individual date type ([**`Date`**](https://docs.rs/chrono/0.4/chrono/struct.Date.html)).
353 It also has time zones attached, and have to be constructed via time zones.
354 Most operations available to `DateTime` are also available to `Date` whenever appropriate.
357 use chrono::prelude::*;
358 use chrono::offset::LocalResult;
360 assert_eq!(Utc::today(), Utc::now().date());
361 assert_eq!(Local::today(), Local::now().date());
363 assert_eq!(Utc.ymd(2014, 11, 28).weekday(), Weekday::Fri);
364 assert_eq!(Utc.ymd_opt(2014, 11, 31), LocalResult::None);
365 assert_eq!(Utc.ymd(2014, 11, 28).and_hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(),
369 There is no timezone-aware `Time` due to the lack of usefulness and also the complexity.
371 `DateTime` has [`date`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.date) method
372 which returns a `Date` which represents its date component.
373 There is also a [`time`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.time) method,
374 which simply returns a naive local time described below.
376 ### Naive date and time
378 Chrono provides naive counterparts to `Date`, (non-existent) `Time` and `DateTime`
379 as [**`NaiveDate`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html),
380 [**`NaiveTime`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveTime.html) and
381 [**`NaiveDateTime`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDateTime.html) respectively.
383 They have almost equivalent interfaces as their timezone-aware twins,
384 but are not associated to time zones obviously and can be quite low-level.
385 They are mostly useful for building blocks for higher-level types.
387 Timezone-aware `DateTime` and `Date` types have two methods returning naive versions:
388 [`naive_local`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_local) returns
389 a view to the naive local time,
390 and [`naive_utc`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_utc) returns
391 a view to the naive UTC time.
395 Only proleptic Gregorian calendar (i.e. extended to support older dates) is supported.
396 Be very careful if you really have to deal with pre-20C dates, they can be in Julian or others.
398 Date types are limited in about +/- 262,000 years from the common epoch.
399 Time types are limited in the nanosecond accuracy.
401 [Leap seconds are supported in the representation but
402 Chrono doesn't try to make use of them](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveTime.html#leap-second-handling).
403 (The main reason is that leap seconds are not really predictable.)
404 Almost *every* operation over the possible leap seconds will ignore them.
405 Consider using `NaiveDateTime` with the implicit TAI (International Atomic Time) scale
408 Chrono inherently does not support an inaccurate or partial date and time representation.
409 Any operation that can be ambiguous will return `None` in such cases.
410 For example, "a month later" of 2014-01-30 is not well-defined
411 and consequently `Utc.ymd(2014, 1, 30).with_month(2)` returns `None`.
413 Non ISO week handling is not yet supported.
414 For now you can use the [chrono_ext](https://crates.io/crates/chrono_ext)
415 crate ([sources](https://github.com/bcourtine/chrono-ext/)).
417 Advanced time zone handling is not yet supported.
418 For now you can try the [Chrono-tz](https://github.com/chronotope/chrono-tz/) crate instead.