
Trying to understand how date works in Rust. Specifically how to get the current local date, and how to manually display a date in a particular format. In the process, we'll touch on two different external date, time crates:time
andchrono
. We'll also look at how to enable crates' features which are disabled by default.
As of the time of writing this post, the 2nd of September, 2023, my Rust “experience” is about 40 (forty) days, and less than 8 (eight) hours a day 😂. This post is intended as a recording of problems which I've come across rather than anything else.
“The book” does not discuss date, time. However, after finishing it, I was under the impression that date, time in Rust is fully the responsibilities of the standard library. Date, time are a complicated business. Coming to any new language, I'm sure we all set aside sometimes to study how date, time work. My first attempt is to get the current local date, and display it in the Australian format, i.e.:dd/mm/yyyy
. E.g.:02/09/2023
.
I expected it to be straight forward like other languageswhich I'm used to. But it is not... After some searching, itseems that there're at least one (1) module and two (2) different crates which deal with date, time:
- Module std::time -- it's part of the standard library. It seems that this module provides system time functionalities, which we can use for tasks such as measuring performance and etc.
- Crate time -- appears to be an external crate, to use it we need to add it to the
[dependencies]
section of theCargo.toml
file. - Crate chrono -- is also an external crate.
The above two (2) crates come up as the first results in the searches that I did. It would seem thatchrono
is also one of the popular, most used one. Presently, I don't know which one isthe one to use -- it does not make sense to use both in a single application?
Please note, example codes in this post have been tested on both Windows 10 and Ubuntu 22.10. For simplicity, I do not do proper error handling, the codes are simple, they should always run successfully anyway.
First, I started looking at date formatting, eventually, I was pointed tocrate time'sparse(...) method -- note the line:
Available oncrate feature
parsing
only.
And the example given:
letformat=format_description!("[year]-[month]-[day]");assert_eq!(Date::parse("2020-01-02",&format)?,date!(2020-01-02));
This example uses two (2) macros:time::macros::format_description andtime::macros::date. Onmacro time::macros::format_description's documentation, I find the following statement a bit confusing:
Available oncrate feature
macros
and (crate featuresformatting
orparsing
) only.
This statement seems to suggest that if we only want to use theparse(...) method andtime::macros::format_description, the crate featureparsing
alone would suffice? But that is not the case, the crate featuremacros
is also required.
And in theFeature flags section ofcrate time:
This crate exposes a number of features. These can be enabled or disabled as shownin Cargo’s documentation. Features aredisabled by default unless otherwise noted.
What that means is, to use thistime crate's above functionalities, we need to include it in theCargo.toml
file as follows:
...[dependencies]time={version="0.3.22",default-features=false,features=["parsing","macros"]}
And below is the complete working version of the above example.
Content of src/main.rs:
usetime::error::Parse;usetime::Date;usetime::macros::{date,format_description};fnmain()->Result<(),Parse>{letformat=format_description!("[year]-[month]-[day]");assert_eq!(Date::parse("2020-01-02",&format)?,date!(2020-01-02));Ok(())}
To format dates, we can use theformat(...) method, which in turn requires theformatting
crate feature. TheCargo.toml
file gets updated as follows:
...[dependencies]time={version="0.3.22",default-features=false,features=["formatting","macros","parsing"]}
And following is the format example I've come up with:
usetime::macros::{date,format_description};fnmain(){letformat=format_description!("[day]/[month]/[year]");letstr=date!(2020-01-02).format(&format).unwrap();println!("[day]/[month]/[year] 2020 - 01 - 02: {}",str);}
Next, to get the current local date. We needstruct time::OffsetDateTime'snow_local() method, and this requires crate featurelocal-offset
enabled:
...[dependencies]time={version="0.3.22",default-features=false,features=["formatting","macros","parsing","local-offset"]}
And below is my learning example:
usetime::OffsetDateTime;usetime::macros::format_description;fnmain(){assert!(OffsetDateTime::now_local().is_ok());println!("{:#?}",OffsetDateTime::now_local());letformat=format_description!("[day]/[month]/[year]");letstr=OffsetDateTime::now_local().unwrap().date().format(&format).unwrap();println!("[day]/[month]/[year]: {}",str);}
Crate chrono seems to be a bit simpler, to get the current local date and display it in the Australian format, we don't have to enable any crate features. Just include the crate:
...[dependencies]chrono="0.4.27"
And below is my learning example code:
usechrono::offset::Local;fnmain(){letdate_time=Local::now();letstr=format!("{}",date_time.format("%d/%m/%Y"));println!("%d/%m/%Y: {}",str);}
This is my first step looking at date in Rust. I've run a lot of the example code from the two crates' documentations, too. Presently, I still don't have a clear understanding of the relationship betweencrate time andcrate chrono -- or even if there's a relationship at all? Both seem to be comprehensive. I don't know when to use which, or just one is enough... I'm guessing, these questions will have their own answers as we go along the Rust journey.
I'm happy with what I've learned in the process of writing this post. Thank you for reading... I do hope this post would help people who're new to Rust like myself. Stay safe as always.
✿✿✿
Feature image source:
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse