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 81the [`time::Duration`](https://docs.rs/time/0.1.40/time/struct.Duration.html) type 82from the `time` crate to represent the magnitude of a time span. 83Since this has the same name as the newer, standard type for duration, 84the reference will refer this type as `OldDuration`. 85Note that this is an "accurate" duration represented as seconds and 86nanoseconds and does not represent "nominal" components such as days or 87months. 88 89Chrono does not yet natively support 90the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type, 91but it will be supported in the future. 92Meanwhile you can convert between two types with 93[`Duration::from_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.from_std) 94and 95[`Duration::to_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.to_std) 96methods. 97 98### Date and Time 99 100Chrono provides a 101[**`DateTime`**](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html) 102type to represent a date and a time in a timezone. 103 104For more abstract moment-in-time tracking such as internal timekeeping 105that is unconcerned with timezones, consider 106[`time::SystemTime`](https://doc.rust-lang.org/std/time/struct.SystemTime.html), 107which tracks your system clock, or 108[`time::Instant`](https://doc.rust-lang.org/std/time/struct.Instant.html), which 109is an opaque but monotonically-increasing representation of a moment in time. 110 111`DateTime` is timezone-aware and must be constructed from 112the [**`TimeZone`**](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html) object, 113which defines how the local date is converted to and back from the UTC date. 114There are three well-known `TimeZone` implementations: 115 116* [**`Utc`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html) specifies the UTC time zone. It is most efficient. 117 118* [**`Local`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html) specifies the system local time zone. 119 120* [**`FixedOffset`**](https://docs.rs/chrono/0.4/chrono/offset/struct.FixedOffset.html) specifies 121 an arbitrary, fixed time zone such as UTC+09:00 or UTC-10:30. 122 This often results from the parsed textual date and time. 123 Since it stores the most information and does not depend on the system environment, 124 you would want to normalize other `TimeZone`s into this type. 125 126`DateTime`s with different `TimeZone` types are distinct and do not mix, 127but can be converted to each other using 128the [`DateTime::with_timezone`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.with_timezone) method. 129 130You can get the current date and time in the UTC time zone 131([`Utc::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html#method.now)) 132or in the local time zone 133([`Local::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html#method.now)). 134 135```rust 136use chrono::prelude::*; 137 138let utc: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z` 139let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00` 140``` 141 142Alternatively, you can create your own date and time. 143This is a bit verbose due to Rust's lack of function and method overloading, 144but in turn we get a rich combination of initialization methods. 145 146```rust 147use chrono::prelude::*; 148use chrono::offset::LocalResult; 149 150let dt = Utc.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z` 151// July 8 is 188th day of the year 2014 (`o` for "ordinal") 152assert_eq!(dt, Utc.yo(2014, 189).and_hms(9, 10, 11)); 153// July 8 is Tuesday in ISO week 28 of the year 2014. 154assert_eq!(dt, Utc.isoywd(2014, 28, Weekday::Tue).and_hms(9, 10, 11)); 155 156let dt = Utc.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); // `2014-07-08T09:10:11.012Z` 157assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_micro(9, 10, 11, 12_000)); 158assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_nano(9, 10, 11, 12_000_000)); 159 160// dynamic verification 161assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(21, 15, 33), 162 LocalResult::Single(Utc.ymd(2014, 7, 8).and_hms(21, 15, 33))); 163assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None); 164assert_eq!(Utc.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None); 165 166// other time zone objects can be used to construct a local datetime. 167// obviously, `local_dt` is normally different from `dt`, but `fixed_dt` should be identical. 168let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); 169let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12); 170assert_eq!(dt, fixed_dt); 171``` 172 173Various properties are available to the date and time, and can be altered individually. 174Most of them are defined in the traits [`Datelike`](https://docs.rs/chrono/0.4/chrono/trait.Datelike.html) and 175[`Timelike`](https://docs.rs/chrono/0.4/chrono/trait.Timelike.html) which you should `use` before. 176Addition and subtraction is also supported. 177The following illustrates most supported operations to the date and time: 178 179```rust 180extern crate time; 181 182use chrono::prelude::*; 183use time::Duration; 184 185// assume this returned `2014-11-28T21:45:59.324310806+09:00`: 186let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806); 187 188// property accessors 189assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28)); 190assert_eq!((dt.month0(), dt.day0()), (10, 27)); // for unfortunate souls 191assert_eq!((dt.hour(), dt.minute(), dt.second()), (21, 45, 59)); 192assert_eq!(dt.weekday(), Weekday::Fri); 193assert_eq!(dt.weekday().number_from_monday(), 5); // Mon=1, ..., Sun=7 194assert_eq!(dt.ordinal(), 332); // the day of year 195assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1 196 197// time zone accessor and manipulation 198assert_eq!(dt.offset().fix().local_minus_utc(), 9 * 3600); 199assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600)); 200assert_eq!(dt.with_timezone(&Utc), Utc.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806)); 201 202// a sample of property manipulations (validates dynamically) 203assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday 204assert_eq!(dt.with_day(32), None); 205assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE 206 207// arithmetic operations 208let dt1 = Utc.ymd(2014, 11, 14).and_hms(8, 9, 10); 209let dt2 = Utc.ymd(2014, 11, 14).and_hms(10, 9, 8); 210assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2)); 211assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2)); 212assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000), 213 Utc.ymd(2001, 9, 9).and_hms(1, 46, 40)); 214assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000), 215 Utc.ymd(1938, 4, 24).and_hms(22, 13, 20)); 216``` 217 218### Formatting and Parsing 219 220Formatting is done via the [`format`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.format) method, 221which format is equivalent to the familiar `strftime` format. 222 223See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers) 224documentation for full syntax and list of specifiers. 225 226The default `to_string` method and `{:?}` specifier also give a reasonable representation. 227Chrono also provides [`to_rfc2822`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.to_rfc2822) and 228[`to_rfc3339`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.to_rfc3339) methods 229for well-known formats. 230 231Chrono now also provides date formatting in almost any language without the 232help of an additional C library. This functionality is under the feature 233`unstable-locales`: 234 235```text 236chrono { version = "0.4", features = ["unstable-locales"] 237``` 238 239The `unstable-locales` feature requires and implies at least the `alloc` feature. 240 241```rust 242use chrono::prelude::*; 243 244let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9); 245assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09"); 246assert_eq!(dt.format("%a %b %e %T %Y").to_string(), "Fri Nov 28 12:00:09 2014"); 247assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), "vendredi 28 novembre 2014, 12:00:09"); 248assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string()); 249 250assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC"); 251assert_eq!(dt.to_rfc2822(), "Fri, 28 Nov 2014 12:00:09 +0000"); 252assert_eq!(dt.to_rfc3339(), "2014-11-28T12:00:09+00:00"); 253assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z"); 254 255// Note that milli/nanoseconds are only printed if they are non-zero 256let dt_nano = Utc.ymd(2014, 11, 28).and_hms_nano(12, 0, 9, 1); 257assert_eq!(format!("{:?}", dt_nano), "2014-11-28T12:00:09.000000001Z"); 258``` 259 260Parsing can be done with three methods: 261 2621. The standard [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait 263 (and [`parse`](https://doc.rust-lang.org/std/primitive.str.html#method.parse) method 264 on a string) can be used for parsing `DateTime<FixedOffset>`, `DateTime<Utc>` and 265 `DateTime<Local>` values. This parses what the `{:?}` 266 ([`std::fmt::Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html)) 267 format specifier prints, and requires the offset to be present. 268 2692. [`DateTime::parse_from_str`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_str) parses 270 a date and time with offsets and returns `DateTime<FixedOffset>`. 271 This should be used when the offset is a part of input and the caller cannot guess that. 272 It *cannot* be used when the offset can be missing. 273 [`DateTime::parse_from_rfc2822`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_rfc2822) 274 and 275 [`DateTime::parse_from_rfc3339`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_rfc3339) 276 are similar but for well-known formats. 277 2783. [`Offset::datetime_from_str`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.datetime_from_str) is 279 similar but returns `DateTime` of given offset. 280 When the explicit offset is missing from the input, it simply uses given offset. 281 It issues an error when the input contains an explicit offset different 282 from the current offset. 283 284More detailed control over the parsing process is available via 285[`format`](https://docs.rs/chrono/0.4/chrono/format/index.html) module. 286 287```rust 288use chrono::prelude::*; 289 290let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9); 291let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600)); 292 293// method 1 294assert_eq!("2014-11-28T12:00:09Z".parse::<DateTime<Utc>>(), Ok(dt.clone())); 295assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<Utc>>(), Ok(dt.clone())); 296assert_eq!("2014-11-28T21:00:09+09:00".parse::<DateTime<FixedOffset>>(), Ok(fixed_dt.clone())); 297 298// method 2 299assert_eq!(DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z"), 300 Ok(fixed_dt.clone())); 301assert_eq!(DateTime::parse_from_rfc2822("Fri, 28 Nov 2014 21:00:09 +0900"), 302 Ok(fixed_dt.clone())); 303assert_eq!(DateTime::parse_from_rfc3339("2014-11-28T21:00:09+09:00"), Ok(fixed_dt.clone())); 304 305// method 3 306assert_eq!(Utc.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone())); 307assert_eq!(Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone())); 308 309// oops, the year is missing! 310assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T %Y").is_err()); 311// oops, the format string does not include the year at all! 312assert!(Utc.datetime_from_str("Fri Nov 28 12:00:09", "%a %b %e %T").is_err()); 313// oops, the weekday is incorrect! 314assert!(Utc.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err()); 315``` 316 317Again : See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers) 318documentation for full syntax and list of specifiers. 319 320### Conversion from and to EPOCH timestamps 321 322Use [`Utc.timestamp(seconds, nanoseconds)`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.timestamp) 323to construct a [`DateTime<Utc>`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html) from a UNIX timestamp 324(seconds, nanoseconds that passed since January 1st 1970). 325 326Use [`DateTime.timestamp`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp) to get the timestamp (in seconds) 327from a [`DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html). Additionally, you can use 328[`DateTime.timestamp_subsec_nanos`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp_subsec_nanos) 329to get the number of additional number of nanoseconds. 330 331```rust 332// We need the trait in scope to use Utc::timestamp(). 333use chrono::{DateTime, TimeZone, Utc}; 334 335// Construct a datetime from epoch: 336let dt = Utc.timestamp(1_500_000_000, 0); 337assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000"); 338 339// Get epoch value from a datetime: 340let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap(); 341assert_eq!(dt.timestamp(), 1_500_000_000); 342``` 343 344### Individual date 345 346Chrono also provides an individual date type ([**`Date`**](https://docs.rs/chrono/0.4/chrono/struct.Date.html)). 347It also has time zones attached, and have to be constructed via time zones. 348Most operations available to `DateTime` are also available to `Date` whenever appropriate. 349 350```rust 351use chrono::prelude::*; 352use chrono::offset::LocalResult; 353 354assert_eq!(Utc::today(), Utc::now().date()); 355assert_eq!(Local::today(), Local::now().date()); 356 357assert_eq!(Utc.ymd(2014, 11, 28).weekday(), Weekday::Fri); 358assert_eq!(Utc.ymd_opt(2014, 11, 31), LocalResult::None); 359assert_eq!(Utc.ymd(2014, 11, 28).and_hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(), 360 "070809"); 361``` 362 363There is no timezone-aware `Time` due to the lack of usefulness and also the complexity. 364 365`DateTime` has [`date`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.date) method 366which returns a `Date` which represents its date component. 367There is also a [`time`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.time) method, 368which simply returns a naive local time described below. 369 370### Naive date and time 371 372Chrono provides naive counterparts to `Date`, (non-existent) `Time` and `DateTime` 373as [**`NaiveDate`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html), 374[**`NaiveTime`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveTime.html) and 375[**`NaiveDateTime`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDateTime.html) respectively. 376 377They have almost equivalent interfaces as their timezone-aware twins, 378but are not associated to time zones obviously and can be quite low-level. 379They are mostly useful for building blocks for higher-level types. 380 381Timezone-aware `DateTime` and `Date` types have two methods returning naive versions: 382[`naive_local`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_local) returns 383a view to the naive local time, 384and [`naive_utc`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_utc) returns 385a view to the naive UTC time. 386 387## Limitations 388 389Only proleptic Gregorian calendar (i.e. extended to support older dates) is supported. 390Be very careful if you really have to deal with pre-20C dates, they can be in Julian or others. 391 392Date types are limited in about +/- 262,000 years from the common epoch. 393Time types are limited in the nanosecond accuracy. 394 395[Leap seconds are supported in the representation but 396Chrono doesn't try to make use of them](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveTime.html#leap-second-handling). 397(The main reason is that leap seconds are not really predictable.) 398Almost *every* operation over the possible leap seconds will ignore them. 399Consider using `NaiveDateTime` with the implicit TAI (International Atomic Time) scale 400if you want. 401 402Chrono inherently does not support an inaccurate or partial date and time representation. 403Any operation that can be ambiguous will return `None` in such cases. 404For example, "a month later" of 2014-01-30 is not well-defined 405and consequently `Utc.ymd(2014, 1, 30).with_month(2)` returns `None`. 406 407Non ISO week handling is not yet supported. 408For now you can use the [chrono_ext](https://crates.io/crates/chrono_ext) 409crate ([sources](https://github.com/bcourtine/chrono-ext/)). 410 411Advanced time zone handling is not yet supported. 412For now you can try the [Chrono-tz](https://github.com/chronotope/chrono-tz/) crate instead. 413 414