1[Chrono][docsrs]: Date and Time for Rust 2======================================== 3 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] 8 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 17 18It aims to be a feature-complete superset of 19the [time](https://github.com/rust-lang-deprecated/time) library. 20In particular, 21 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. 25 26There were several previous attempts to bring a good date and time library to Rust, 27which Chrono builds upon and should acknowledge: 28 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) 33 34Any significant changes to Chrono are documented in 35the [`CHANGELOG.md`](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) file. 36 37 38## Usage 39 40Put this in your `Cargo.toml`: 41 42```toml 43[dependencies] 44chrono = "0.4" 45``` 46 47### Features 48 49Chrono supports various runtime environments and operating systems, and has 50several features that may be enabled or disabled. 51 52Default features: 53 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 57 and traits. 58- `clock`: enables reading the system time (`now`), independent of whether 59 `std::time::SystemTime` is present, depends on having a libc. 60 61Optional features: 62 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. 68 69[`serde`]: https://github.com/serde-rs/serde 70[wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen 71 72See the [cargo docs][] for examples of specifying features. 73 74[cargo docs]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#choosing-features 75 76## Overview 77 78### Duration 79 80Chrono currently uses its own [`Duration`] type to represent the magnitude 81of a time span. Since this has the same name as the newer, standard type for 82duration, the reference will refer this type as `OldDuration`. 83 84Note that this is an "accurate" duration represented as seconds and 85nanoseconds and does not represent "nominal" components such as days or 86months. 87 88When 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) 90type from v0.1 of the time crate. time v0.1 is deprecated, so new code 91should disable the `oldtime` feature and use the `chrono::Duration` type 92instead. The `oldtime` feature is enabled by default for backwards 93compatibility, but future versions of Chrono are likely to remove the 94feature entirely. 95 96Chrono does not yet natively support 97the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type, 98but it will be supported in the future. 99Meanwhile 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) 101and 102[`Duration::to_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.to_std) 103methods. 104 105### Date and Time 106 107Chrono provides a 108[**`DateTime`**](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html) 109type to represent a date and a time in a timezone. 110 111For more abstract moment-in-time tracking such as internal timekeeping 112that is unconcerned with timezones, consider 113[`time::SystemTime`](https://doc.rust-lang.org/std/time/struct.SystemTime.html), 114which tracks your system clock, or 115[`time::Instant`](https://doc.rust-lang.org/std/time/struct.Instant.html), which 116is an opaque but monotonically-increasing representation of a moment in time. 117 118`DateTime` is timezone-aware and must be constructed from 119the [**`TimeZone`**](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html) object, 120which defines how the local date is converted to and back from the UTC date. 121There are three well-known `TimeZone` implementations: 122 123* [**`Utc`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html) specifies the UTC time zone. It is most efficient. 124 125* [**`Local`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html) specifies the system local time zone. 126 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. 132 133`DateTime`s with different `TimeZone` types are distinct and do not mix, 134but can be converted to each other using 135the [`DateTime::with_timezone`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.with_timezone) method. 136 137You 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)) 139or in the local time zone 140([`Local::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html#method.now)). 141 142```rust 143use chrono::prelude::*; 144 145let utc: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z` 146let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00` 147``` 148 149Alternatively, you can create your own date and time. 150This is a bit verbose due to Rust's lack of function and method overloading, 151but in turn we get a rich combination of initialization methods. 152 153```rust 154use chrono::prelude::*; 155use chrono::offset::LocalResult; 156 157let 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") 159assert_eq!(dt, Utc.yo(2014, 189).and_hms(9, 10, 11)); 160// July 8 is Tuesday in ISO week 28 of the year 2014. 161assert_eq!(dt, Utc.isoywd(2014, 28, Weekday::Tue).and_hms(9, 10, 11)); 162 163let dt = Utc.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); // `2014-07-08T09:10:11.012Z` 164assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_micro(9, 10, 11, 12_000)); 165assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_nano(9, 10, 11, 12_000_000)); 166 167// dynamic verification 168assert_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))); 170assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None); 171assert_eq!(Utc.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None); 172 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. 175let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); 176let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12); 177assert_eq!(dt, fixed_dt); 178``` 179 180Various properties are available to the date and time, and can be altered individually. 181Most 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. 183Addition and subtraction is also supported. 184The following illustrates most supported operations to the date and time: 185 186```rust 187 188use chrono::prelude::*; 189use chrono::Duration; 190 191// assume this returned `2014-11-28T21:45:59.324310806+09:00`: 192let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806); 193 194// property accessors 195assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28)); 196assert_eq!((dt.month0(), dt.day0()), (10, 27)); // for unfortunate souls 197assert_eq!((dt.hour(), dt.minute(), dt.second()), (21, 45, 59)); 198assert_eq!(dt.weekday(), Weekday::Fri); 199assert_eq!(dt.weekday().number_from_monday(), 5); // Mon=1, ..., Sun=7 200assert_eq!(dt.ordinal(), 332); // the day of year 201assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1 202 203// time zone accessor and manipulation 204assert_eq!(dt.offset().fix().local_minus_utc(), 9 * 3600); 205assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600)); 206assert_eq!(dt.with_timezone(&Utc), Utc.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806)); 207 208// a sample of property manipulations (validates dynamically) 209assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday 210assert_eq!(dt.with_day(32), None); 211assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE 212 213// arithmetic operations 214let dt1 = Utc.ymd(2014, 11, 14).and_hms(8, 9, 10); 215let dt2 = Utc.ymd(2014, 11, 14).and_hms(10, 9, 8); 216assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2)); 217assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2)); 218assert_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)); 220assert_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)); 222``` 223 224### Formatting and Parsing 225 226Formatting is done via the [`format`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.format) method, 227which format is equivalent to the familiar `strftime` format. 228 229See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers) 230documentation for full syntax and list of specifiers. 231 232The default `to_string` method and `{:?}` specifier also give a reasonable representation. 233Chrono 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 235for well-known formats. 236 237Chrono now also provides date formatting in almost any language without the 238help of an additional C library. This functionality is under the feature 239`unstable-locales`: 240 241```text 242chrono { version = "0.4", features = ["unstable-locales"] 243``` 244 245The `unstable-locales` feature requires and implies at least the `alloc` feature. 246 247```rust 248use chrono::prelude::*; 249 250let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9); 251assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09"); 252assert_eq!(dt.format("%a %b %e %T %Y").to_string(), "Fri Nov 28 12:00:09 2014"); 253assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), "vendredi 28 novembre 2014, 12:00:09"); 254assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string()); 255 256assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC"); 257assert_eq!(dt.to_rfc2822(), "Fri, 28 Nov 2014 12:00:09 +0000"); 258assert_eq!(dt.to_rfc3339(), "2014-11-28T12:00:09+00:00"); 259assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z"); 260 261// Note that milli/nanoseconds are only printed if they are non-zero 262let dt_nano = Utc.ymd(2014, 11, 28).and_hms_nano(12, 0, 9, 1); 263assert_eq!(format!("{:?}", dt_nano), "2014-11-28T12:00:09.000000001Z"); 264``` 265 266Parsing can be done with three methods: 267 2681. 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. 274 2752. [`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) 280 and 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. 283 2843. [`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. 289 290More detailed control over the parsing process is available via 291[`format`](https://docs.rs/chrono/0.4/chrono/format/index.html) module. 292 293```rust 294use chrono::prelude::*; 295 296let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9); 297let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600)); 298 299// method 1 300assert_eq!("2014-11-28T12:00:09Z".parse::<DateTime<Utc>>(), Ok(dt.clone())); 301assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<Utc>>(), Ok(dt.clone())); 302assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<FixedOffset>>(), Ok(fixed_dt.clone())); 303 304// method 2 305assert_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())); 307assert_eq!(DateTime::parse_from_rfc2822("Fri, 28 Nov 2014 21:00:09 +0900"), 308 Ok(fixed_dt.clone())); 309assert_eq!(DateTime::parse_from_rfc3339("2014-11-28T21:00:09+09:00"), Ok(fixed_dt.clone())); 310 311// method 3 312assert_eq!(Utc.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone())); 313assert_eq!(Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone())); 314 315// oops, the year is missing! 316assert!(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! 318assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T").is_err()); 319// oops, the weekday is incorrect! 320assert!(Utc.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err()); 321``` 322 323Again : See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers) 324documentation for full syntax and list of specifiers. 325 326### Conversion from and to EPOCH timestamps 327 328Use [`Utc.timestamp(seconds, nanoseconds)`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.timestamp) 329to 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). 331 332Use [`DateTime.timestamp`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp) to get the timestamp (in seconds) 333from 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) 335to get the number of additional number of nanoseconds. 336 337```rust 338// We need the trait in scope to use Utc::timestamp(). 339use chrono::{DateTime, TimeZone, Utc}; 340 341// Construct a datetime from epoch: 342let dt = Utc.timestamp(1_500_000_000, 0); 343assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000"); 344 345// Get epoch value from a datetime: 346let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap(); 347assert_eq!(dt.timestamp(), 1_500_000_000); 348``` 349 350### Individual date 351 352Chrono also provides an individual date type ([**`Date`**](https://docs.rs/chrono/0.4/chrono/struct.Date.html)). 353It also has time zones attached, and have to be constructed via time zones. 354Most operations available to `DateTime` are also available to `Date` whenever appropriate. 355 356```rust 357use chrono::prelude::*; 358use chrono::offset::LocalResult; 359 360assert_eq!(Utc::today(), Utc::now().date()); 361assert_eq!(Local::today(), Local::now().date()); 362 363assert_eq!(Utc.ymd(2014, 11, 28).weekday(), Weekday::Fri); 364assert_eq!(Utc.ymd_opt(2014, 11, 31), LocalResult::None); 365assert_eq!(Utc.ymd(2014, 11, 28).and_hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(), 366 "070809"); 367``` 368 369There is no timezone-aware `Time` due to the lack of usefulness and also the complexity. 370 371`DateTime` has [`date`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.date) method 372which returns a `Date` which represents its date component. 373There is also a [`time`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.time) method, 374which simply returns a naive local time described below. 375 376### Naive date and time 377 378Chrono provides naive counterparts to `Date`, (non-existent) `Time` and `DateTime` 379as [**`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. 382 383They have almost equivalent interfaces as their timezone-aware twins, 384but are not associated to time zones obviously and can be quite low-level. 385They are mostly useful for building blocks for higher-level types. 386 387Timezone-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 389a view to the naive local time, 390and [`naive_utc`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_utc) returns 391a view to the naive UTC time. 392 393## Limitations 394 395Only proleptic Gregorian calendar (i.e. extended to support older dates) is supported. 396Be very careful if you really have to deal with pre-20C dates, they can be in Julian or others. 397 398Date types are limited in about +/- 262,000 years from the common epoch. 399Time types are limited in the nanosecond accuracy. 400 401[Leap seconds are supported in the representation but 402Chrono 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.) 404Almost *every* operation over the possible leap seconds will ignore them. 405Consider using `NaiveDateTime` with the implicit TAI (International Atomic Time) scale 406if you want. 407 408Chrono inherently does not support an inaccurate or partial date and time representation. 409Any operation that can be ambiguous will return `None` in such cases. 410For example, "a month later" of 2014-01-30 is not well-defined 411and consequently `Utc.ymd(2014, 1, 30).with_month(2)` returns `None`. 412 413Non ISO week handling is not yet supported. 414For now you can use the [chrono_ext](https://crates.io/crates/chrono_ext) 415crate ([sources](https://github.com/bcourtine/chrono-ext/)). 416 417Advanced time zone handling is not yet supported. 418For now you can try the [Chrono-tz](https://github.com/chronotope/chrono-tz/) crate instead. 419 420