Home Rhyylen
Contatto
 
 
 
Rust Language
Capitolo 46
Gestione del tempo (cenni)

Prendiamoci una piccola pausa dal complesso mondo del parallelismo e della concorrenza per introdurre un argomento soltanto sfiorato nei paragrafi precedenti. La gestione del tempo è importante in molti applicativi e la sua conoscenza vi tornerà utile prima o poi. E' solo una questione... di tempo.
In questo paragrafo, puramente introduttivo (ok, trovo l'argomento un po' noioso), darò un taglio molto pratico, la teoria sottostante è abbastanza pesante e non del tutto semplice.
Iniziamo quindi dalle basi, come sempre, ovvero stampare a video data e ora corrente. Ebbene, non è così immediato come in altri linguaggi, Rust è Rust nel bene e nel male. In Python potreste fare molto semplicemente come segue:

from datetime import datetime
now = datetime.now()
formatted_date_time = now.strftime("%d/%m/%Y %H:%M:%S")
print("Data e ora attuali:", formatted_date_time)


a parte i parametri di formattazione è tutto abbastanza semplice. In C# si istanzia il potente oggetto DateTime e ve la cavate con poco, più o meno. Ma in Rust, se si vuole offrire una formattazione ideale bisogna fare uso del crate chrono (questa almeno è la strada che io prediligo, anche se non l'unica). E stavolta dobbiamo lavorare con cargo in modo da creare facilmente il nostro cargo.toml. Questo appunto per importare ed usare il nostro crate. Quindi, passo dopo passo

cargo new tempo

questo crea la seguente struttura:



modifico Cargo.toml come segue:

[package]
name = "time"
version = "0.1.0"
edition = "2024"

[dependencies]
chrono = "0.4.41"


e nella directory src il file main.rs dovrà diventare come segue:

use chrono::Local;
fn main() {
    let now = Local::now();
    println!("Data e ora locale: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
E vediamo cosa questo significa:  
la prima riga in particolare è molto interessante. Importa il tipo, o meglio la struct Local dal crate chrono. Local rappresenta l'orologio del sistema nella timezone locale
Local::now() restituisce una struct DateTime<Local> che memorizziamo in now. Dentro now abbiamo a questo punto tutte le informazioni che ci servono. Da notare la formattazione dell'output:

Specificatore Significato Esempio
%Y Anno (4 cifre) 2025
%m Mese (2 cifre) 05
%d Giorno 26
%H Ora (24h) 15
%M Minuti 32
%S Secondi 10


Può essere interessante, da un punto di vista pratico, estrarre giorno, mese ed anno e memorizzarli in un array, anzi in 3 array differenti per permetterne successive elaborazioni. Fermo restando la configurazione di cargo.toml il codice potrebbe essere questo:

  Esempio 46.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use chrono::{Datelike, Local};
fn main() {
    let now = Local::now().date_naive(); /
    // Estrai giorno, mese, anno come stringhe con padding
    let giorno_str = format!("{:02}", now.day());
    let mese_str = format!("{:02}", now.month());
    let anno_str = format!("{:04}", now.year());
    // Converti le stringhe in array di caratteri
    let giorno: [char; 2] = giorno_str.chars().collect::<Vec<_>>().try_into().unwrap();
    let mese: [char; 2] = mese_str.chars().collect::<Vec<_>>().try_into().unwrap();
    let anno: [char; 4] = anno_str.chars().collect::<Vec<_>>().try_into().unwrap();
    // Stampa di controllo
    println!("Giorno: {:?}", giorno);
    println!("Mese:   {:?}", mese);
    println!("Anno:   {:?}", anno);
}

Se fosse necessario ricavare ore, minuti e secondi, alle righe 5, 6 e 7 dovremmo usare hour(), minute() e second() invece di day(), month() e year(), nell'ordine che preferite naturalmente. Avrete senza dubbio notato he abbiamo usato date_naive, una struct anh'essa appartenente al crate chrono, ma più semplice e senza fuso orario associato. 

Come ultimo esempio, vediamo come calcolare la differenza tra due date:

  Esempio 46.2
1
2
3
4
5
6
7
8
9
use chrono::{NaiveDate};
fn main() {
    // Definisci due date
    let data1 = NaiveDate::from_ymd_opt(2025, 5, 31).unwrap();
    let data2 = NaiveDate::from_ymd_opt(2025, 6, 10).unwrap();
    // Calcola la differenza in giorni
    let differenza = (data2 - data1).num_days();
    println!("Differenza in giorni: {}", differenza);
}

Oppure, anche in maniera più dettagliata

  Esempio 46.3
1
2
3
4
5
6
7
8
9
10
use chrono::{DateTime, Local, Duration};
fn main() {
    let data1: DateTime<Local> = Local::now();
    let data2: DateTime<Local> = data1 + Duration::days(10); // Data 10 giorni dopo
    let differenza = data2.signed_duration_since(data1);
    println!("Differenza in giorni: {}", differenza.num_days());
    println!("Differenza in ore: {}", differenza.num_hours());
    println!("Differenza in minuti: {}", differenza.num_minutes());
    println!("Differenza in secondi: {}", differenza.num_seconds());
}

Terminiamo qui queste informazioni assolutamente di base, utili per iniziare a lavorare. Mi riservo di approfondire il discorso in futuro.