Professional Documents
Culture Documents
_Time
_Time
_Time
And more...
Getting started
This short tutorial describes basic usage of time , to get operational quickly.
[dependencies]
time = { version = "0.3", features = ["macros"] }
2. Get the current time With the crate feature std a UTC offset ( OffsetDateTime ) is
available, but with the crate feature local-offset , we can also get the local time.
use time::OffsetDateTime;
println!("{now}");
3. Create dates and times. We can create dates ( Date ), dates with times
( PrimitiveDateTime ) and date times with an UTC offset ( OffsetDateTime ). A simple
Time is also available.
use time::{Date, PrimitiveDateTime, OffsetDateTime, UtcOffset};
use time::Weekday::Wednesday;
use time::Duration;
use time::macros::{datetime};
println!("{}", b - a);
// 2h59m5s
time vs chrono
time 0.1 was originally a thin wrapper around libc time functions. Because it was relatively
barebones, chrono was developed as a richer API on top of time 0.1.
Around 2019, the time crate, which was unmaintained since August 2016, was picked up for
maintenance again. time has since been rewritten as of time 0.2, and is incompatible with the
0.1 version.
Today:
time has been rewritten from 0.1,and is actively developed.
chrono depends on time 0.1, an old version unrelated with current time , and is actively
developed as well.
Since they are incompatible with each other, please choose the library that fits your needs.
Create dates and times
time provides a const -ready API. All functions here are const : values can be computed at
compile-time if you pass constants, with no difference if used at runtime.
For convenience, macros are provided with feature macros . They let us restrict parameters
further, avoiding the need to unwrap() at the cost of compilation time.
Creating Date s
From a constant value, with feature macros :
use time::macros::date;
let _ = date!(2022-01-02);
Creating PrimitiveDateTime s
A PrimitiveDateTime is both a date and a time. We can create them directly:
use time::macros::datetime;
Creating OffsetDateTime s
An OffsetDateTime is a date, time and UTC offset . Use it if you deal with timezones:
use time::macros::datetime;
// With UTC:
let _ = dt.assume_utc();
// or with another offset:
let _ = dt.assume_offset(UtcOffset::from_hms(1, 2, 3));
// with macros:
let _ = dt.assume_offset(offset!(-11));
Parse dates
time has can parse datetimes from strings, in any given format.
2. Using the common ISO 8601 format, via the Iso8601 format description:
use time::format_description::well_known::Iso8601;
use time::PrimitiveDateTime;
1. Enable feature macros and parsing . macros are used to call format_description! , but
you can also call the equivalent function.
use time::macros::format_description;
use time::Time;
2. Create a struct and parse from a format, eg. JSON using serde-json :
use time::macros::format_description;
use time::{OffsetDateTime, Time};
use serde::{Deserialize};
#[derive(Deserialize)]
struct Notification {
message: String,
#[serde(with = "time::serde::iso8601")]
timestamp: OffsetDateTime,
}
fn main() {
let input = r#"{
"message": "foo",
"timestamp": "2022-01-02T11:12:13Z"
}"#;
The following types currently implement both the Formattable and Parsable traits:
FormatItem<'_>
[FormatItem<'_>]
T where <T as Deref>::Target: Formattable (or Parsable )
All well known formats
If the format description is statically known, you should use the format_description! macro.
This is identical to the format_description::parse method, but runs at compile-time,
throwing an error if the format description is invalid. If you do not know the desired format
statically (such as if you are using one provided by the user), you should use the
format_description::parse_owned method (or similar method in the format_description
module), which is fallible.
Format descriptions have components and literals. Literals are formatted and parsed as-is.
Components are the mechanism by which values (such as a Time or Date ) are dynamically
formatted and parsed. They have significant flexibility, allowing for differences in padding,
variable widths for subsecond values, numerical or textual representations, and more.
Either a literal or a component may be present at the start of the format description. It is valid
to have both consecutive literals and consecutive components. Components must be fully
contained between brackets with optional whitespace. Escaping behavior varies by version, and
is described below.
Versioning
There are multiple versions of the format description syntax in time . Similar to Rust editions,
all versions are and will remain supported indefinitely. Some features may only be available in
newer versions for technical reasons.
In most cases, you do not need to worry about the version of the format description. However,
there are some differences.
Differences
] ] \]
\ \ \\
[first] and [optional] are supported in both version 1 and version 2, but individual
methods may prevent their use. This is because some methods return a format description
that is entirely borrowed. However, when parsing [first] and [optional] , the generated
sequence is necessarily owned. For this reason, you will need to use the
format_description::parse_owned method or the format_description! macro to use these
components.
Version used
format_description::parse uses version 1 unconditionally. This is the only method that has a
non-configurable version. format_description::parse_borrowed and
format_description::parse_owned require the user to specify the version. If the version is not
valid, compilation will fail. format_description! defaults to version 1, but can be configured to
use a different version.
Configuring format_description!
use time::macros::format_description;
// 0 is not a valid version, so compilation will fail.
let _ = format_description!(version = 0, "[hour]:[minute]:[second]");
Version 1
literal
[[
Version 2
literal
\ [
\ is used to begin an escape sequence. Currently, the only valid escape sequences are \[ ,
\] , and \\ . Any other character following \ is invalid.
Components
Follows is the syntax for all components in alphabetical order. Any of the following may be
used where component is present in the above diagram. "Whitespace" refers to any non-empty
sequence of ASCII whitespace characters.
Day of month: [day]
space
none
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
A series of FormatItem s (or OwnedFormatItem s) where, when parsing, the first successful
parse is used. When formatting, the first item is used.
end
This component indicates the end of the input. When formatting, it is a no-op. When
parsing, it will only succeed if there is no further input. It does not consume any input.
space
none
repr: 24
12
The padded value has a width of 2. You can choose between padding with zeroes,
spacing, or having no padding at all. The default is to pad the value with zeroes.
Users have the option to choose between two representations. One is the 12-hour clock,
frequently used in the Anglosphere, while the alternative (the 24-hour clock) is frequently
used elsewhere. The 12-hour clock is typically used in conjunction with AM/PM.
When parsing, this ignores the indicated number of bytes. This component is a no-op
when formatting. The count modifier is mandatory. Its value must be a positive integer.
space
none
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
Month: [month]
space
none
repr: numerical
long
short
case_sensitive: true
false
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
Users have the option to choose between three representations. The default is numerical.
Alternatives are long and short, both of which are textual formats and have no padding.
The long format is the full English name of the month, while the short format is the first
three letters of it.
space
none
sign: automatic
mandatory
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
Users have the option to choose whether the sign is automatic (the default) or mandatory.
If the sign is automatic, it will only be present when the value is negative. If mandatory, it
will always be present.
space
none
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
space
none
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
space
none
The padded value has a width of 3. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
AM/PM: [period]
upper
case_sensitive: true
false
Users have the option to choose whether the value is uppercase or lowercase. This
component is typically used in conjunction with the hour of the day with repr:12 .
space
none
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
Users have the choice of how many digits should be displayed or parsed. By default, this
is one or more, where the minimum number of digits will be used when formatting and
any nonzero number of digits are accepted by the parser (though digits after the ninth will
be discarded). There is the option to require a fixed number of digits between one and
nine. When formatting, the value is not rounded if more digits would otherwise be
present.
millisecond
microsecond
nanosecond
sign: automatic
mandatory
Users can choose between four levels of precision: second (the default), millisecond,
microsecond, and nanosecond. The sign can also be made mandatory rather than optional.
space
none
repr: iso
sunday
monday
The padded value has a width of 2. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
Users can choose between three representations: iso (the default), sunday, and monday.
ISO week numbers are in between 1 and 53, while others are between 0 and 53. ISO week
one is the Monday-to-Sunday week that contains January 4. Week one of other
representations begins on the first instance of that day in the calendar year (e.g. Sunday-
based week numbering has week one start on the first Sunday of the year).
short
sunday
monday
one_indexed: false
true
case_sensitive: true
false
Users can choose between a number of representations for the day of the week. There
are long (the default) and short, both of which are textual representations; the long
representation is the weekday's full name in English, while the short is the first three
letters. There are also sunday and monday representations, which are numerical. These
formats are either zero to six or one to seven (depending on whether one_indexed is
false or true, respectively), with the named day being at the start of that range.
Year: [year]
year whitespace padding: zero
space
none
repr: full
last_two
base: calendar
iso_week
sign: automatic
mandatory
The padded value has a width of 4. You can choose between padding with zeroes, spaces,
or having no padding at all. The default is to pad the value with zeroes.
Users can choose between two representations: the full year (the default) and the last two
digits of the year. This should be relatively straightforward. Note that when parsing, if only
the last two digits of the year are present, the value returned may not be what was
expected — if the return is successful at all (it's not guaranteed).
There are two bases for the year: calendar and iso_week. The former is what you want if
using the month, day, ordinal, or similar. You likely only want to use iso_week if you are
using the week number with repr:iso . Don't be like Twitter; know which should be used
when.
Users have the option to choose whether the sign is automatic (the default) or mandatory.
If the sign is automatic, it will only be present when the value is negative or if the large-
dates feature is enabled and the value contains more than four digits. If mandatory, it will
always be present.
When the large-dates feature is enabled, ambiguities may exist when parsing. For
example, if a year is immediately followed by the week number, the parser will eagerly
consume six digits even if the year should only be four and the week number the
remaining two.
Well-known format descriptions
A number of well-known format descriptions are provided by time . These are intended to be
used when you need to be fully compliant with a specification. Many specifications have
various edge-cases that are difficult to model with a custom format description. Using a well-
known format description allows you to handle all relevant edge cases.
Guarantees
The guarantees provided by well-known formats are deliberately minimal. The only guarantees,
unless otherwise documented, are:
If you are expecting a specific output and not just any valid output, you should use a custom
format.
Mutual agreement
Some well-known format descriptions require mutual agreement for certain behavior. For
example, ISO 8601 requires that the year be four digits unless additional digits are mutually
agreed upon. time inherently has no way to enforce mutual agreement. As such, it is assumed
to be present. If you are using the default configuration, you must ensure that the other party
is able to accept the formatted value.
ISO 8601
The format described in ISO 8601. It can be found in the api documentation here.
The examples and format description shown below are for the default configuration. Various
options are available for this format which you can change. Additional information can be
found in the configuration api documentation.
Note: When using the time::serde::iso8601 module in conjunction with serde , the default
configuration is different. In that case, the years are always six digits and preceded by a sign.
Examples:
1997-11-12T09:55:06.000000000-06:00
2022-09-08T13:55:24.000000000+02:00
2010-03-14T18:32:03.000000000Z
RFC 2822
The format described in RFC 2822. It can be found in the api documentation here.
Examples:
RFC 3339
The format described in RFC 3339. It can be found in the api documentation here.
Examples:
1997-11-12T09:55:06-06:00
2022-09-08T13:55:24+02:00
2010-03-14T18:32:03Z
.nanoseconds()
.microseconds()
.milliseconds()
.seconds()
.minutes()
.hours()
.days()
.weeks()
.std_nanoseconds()
.std_microseconds()
.std_milliseconds()
.std_seconds()
.std_minutes()
.std_hours()
.std_days()
.std_weeks()
The NumericalDuration trait is implemented for i64 and f64 , such that both integer and
float literals are able to use the methods. The NumericalStdDuration trait is implemented for
u64 and f64 for the same reasons, though the latter will perform a runtime check ensuring
the value is non-negative.
While it is possible to use these extension methods on non-literals, such usage is discouraged
for ease of reading.
Utility functions
Interop with stdlib
Feature flags
serde
rand
quickcheck
Guarantees
Period type
tzdb support
0.2 to 0.3
Disclaimer
Date algorithms
Internal representation
Hacks
Testing
Benchmarks
Resources
GitHub
Issue tracker
Discussions
crates.io
docs.rs