Duration and Calculation
Measure the elapsed time between two code sections
Measures time::Instant::elapsed since time::Instant::now.
Calling time::Instant::elapsed returns a time::Duration that we print at the end of the recipe.
This method will not mutate or reset the time::Instant object.
use std::time::{Duration, Instant};
use std::thread;
fn expensive_function() {
thread::sleep(Duration::from_secs(1));
}
fn main() {
let start = Instant::now();
expensive_function();
let duration = start.elapsed();
println!("Time elapsed in expensive_function() is: {:?}", duration);
}
Deadline arithmetic with Instant
Calculates a one second Duration. Computes deadline one second from Instant::now.
Sleeps for one second and compares deadline with Instant::now to check if the deadline has passed.
use std::thread;
use std::time::{Duration, Instant};
fn sleep(duration: Duration) {
thread::sleep(duration);
}
fn main() {
let one_second = Duration::from_secs(1);
let deadline = Instant::now() + one_second;
sleep(Duration::from_secs(1));
if Instant::now() > deadline {
println!("Deadline has passed");
}
}
Convert SystemTime to Unix timestamp
Converts the current SystemTime to seconds since the Unix epoch, then computes the original time
by adding the unix timestamp to SystemTime::UNIX_EPOCH constant.
use std::time::{SystemTime, SystemTimeError};
fn main() -> Result<(), SystemTimeError> {
let now = SystemTime::now();
let since_unix_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
println!("Unix timestamp: {}", since_unix_epoch.as_secs());
let from_unix_timestamp = SystemTime::UNIX_EPOCH + since_unix_epoch;
println!("Back to SystemTime: {:?}", from_unix_timestamp);
Ok(())
}
Benchmark a closure with Instant
Initializes a weights vector, calculates half of its total sum into half_load,
and uses benchmark to measure the performance of subset_sum which takes a slice of weights and a target value and finds a subset whose weights sum to the target.
benchmark measures the average time required to call a closure a specified number of times using Instant::now and Instant::elapsed.
It uses black_box to prevent the compiler from optimizing away the closure’s computation since its return value is ignored.
use std::time::{Duration, Instant};
fn subset_sum(weights: &[u64], target: u64) -> Option<u32> {
for mask in 0..1u32 << weights.len() {
let sum: u64 = weights
.iter()
.enumerate()
.filter(|(i, _)| mask >> i & 1 == 1)
.map(|(_, weight)| weight)
.sum();
if sum == target {
return Some(mask);
}
}
None
}
fn benchmark<F, T>(runs: u32, mut f: F) -> Duration
where
F: FnMut() -> T,
{
let start = Instant::now();
for _ in 0..runs {
std::hint::black_box(f());
}
start.elapsed() / runs
}
fn main() {
let weights: Vec<u64> = (1..=18).map(|kg| kg * 2).collect();
let half_load = weights.iter().sum::<u64>() / 2;
for parcels in 12..=weights.len() {
let mean = benchmark(3, || subset_sum(&weights[..parcels], half_load));
println!("{:2} parcels: {:>10.2?}", parcels, mean);
}
}
Choosing between chrono, time and jiff
chronoandtimeare both very widely used, and both are supported by crates such asserde,dieselandsqlx.chronohas a larger API, but needs the separatechrono-tzcrate for IANA time zones.timeis smaller and only knows fixed UTC offsets, with no time zone database.jiffhas IANA time zone support built in, using the system’s time zone database, or a bundled copy on platforms without one. ItsSpanandZonedtypes make DST-aware arithmetic the default. It has fewer third-party integrations so far.- All three are pre-1.0, so their APIs may still change.
If your code works with time zones and has no existing chrono or time
dependency, jiff is worth considering. Otherwise stay with whatever your
dependencies already use.
Perform checked date and time calculations
Calculates and displays the date and time two weeks from now using
DateTime::checked_add_signed and the date of the day before that using
DateTime::checked_sub_signed. The methods return None if the date and time
cannot be calculated.
Escape sequences that are available for the
DateTime::format can be found at chrono::format::strftime.
use chrono::{DateTime, Duration, Utc};
fn day_earlier(date_time: DateTime<Utc>) -> Option<DateTime<Utc>> {
date_time.checked_sub_signed(Duration::days(1))
}
fn main() {
let now = Utc::now();
println!("{}", now);
let almost_three_weeks_from_now = now
.checked_add_signed(Duration::weeks(2))
.and_then(|in_2weeks| in_2weeks.checked_add_signed(Duration::weeks(1)))
.and_then(day_earlier);
match almost_three_weeks_from_now {
Some(x) => println!("{}", x),
None => eprintln!("Almost three weeks from now overflows!"),
}
match now.checked_add_signed(Duration::max_value()) {
Some(x) => println!("{}", x),
None => eprintln!(
"We can't use chrono to tell the time for the Solar System to complete more than one full orbit around the galactic center."
),
}
}
Convert a local time to another timezone
Gets the local time and displays it using offset::Local::now and then converts it to the UTC standard using the DateTime::from_utc struct method. A time is then converted using the offset::FixedOffset struct and the UTC time is then converted to UTC+8 and UTC-2.
use chrono::{DateTime, FixedOffset, Local, Utc};
fn main() {
let local_time = Local::now();
let utc_time = DateTime::<Utc>::from_utc(local_time.naive_utc(), Utc);
let china_timezone = FixedOffset::east(8 * 3600);
let rio_timezone = FixedOffset::west(2 * 3600);
println!("Local time now is {}", local_time);
println!("UTC time now is {}", utc_time);
println!(
"Time in Hong Kong now is {}",
utc_time.with_timezone(&china_timezone)
);
println!(
"Time in Rio de Janeiro now is {}",
utc_time.with_timezone(&rio_timezone)
);
}