• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/H03-May-2022-266220

benches/H03-May-2022-148110

src/H03-May-2022-18,77610,437

tests/H03-May-2022-5947

.cargo-checksum.jsonH A D03-May-202289 11

.cargo_vcs_info.jsonH A D14-Aug-202074 65

.git-ignore-revsH A D24-Jul-202054 21

.gitignoreH A D22-Nov-201918 32

CHANGELOG.mdH A D14-Aug-202022.8 KiB712439

Cargo.tomlH A D14-Aug-20202.8 KiB11192

Cargo.toml.orig-cargoH A D14-Aug-20202.1 KiB7461

README.mdH A D07-Aug-202018.8 KiB414316

rustfmt.tomlH A D24-Jul-202029 21

README.md

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