En Rust, la medición del tiempo se divide principalmente en dos conceptos: el tiempo monótono y el tiempo del reloj del sistema. Para gestionar los intervalos resultantes, se utiliza el tipo Duration.

Instant representa un punto en un reloj monótono. Un reloj monótono es aquel que nunca retrocede, independientemente de si el usuario cambia la hora del sistema o si hay una sincronización de red (NTP). Por esta razón, Instant es la herramienta ideal para realizar benchmarking o medir la duración de un proceso, ya que garantiza que el tiempo siempre avance. Si intentas usar SystemTime para medir intervalos y el reloj del sistema se ajusta hacia atrás durante la ejecución, podrías obtener resultados incoherentes o errores lógicos.

SystemTime representa el tiempo del reloj de pared (wall clock). Este es el tiempo “real” que vemos en el reloj de nuestra computadora. A diferencia de Instant, SystemTime puede retroceder o saltar hacia adelante si el sistema operativo ajusta la hora. Es el tipo adecuado para determinar fechas exactas o para calcular timestamps de Unix (segundos transcurridos desde el 1 de enero de 1970).

Para manejar los intervalos de tiempo, usamos Duration. Este tipo representa una cantidad de tiempo física y permite realizar operaciones matemáticas como sumas, multiplicaciones y comprobaciones de desbordamiento. Si intentas calcular la diferencia de tiempo entre un punto en el futuro y uno en el pasado usando duration_since, el programa provocará un panic. Para evitar esto en cálculos riskosos, se utiliza checked_duration_since, que devuelve un Option.

use std::time::{Instant, SystemTime, Duration};
use std::thread;

fn main() {
    // 1. Medición de rendimiento con Instant (Monotónico)
    let inicio = Instant::now();
    
    // Simulamos una tarea que tarda algo de tiempo
    thread::sleep(Duration::from_millis(500));
    
    let final_instant = Instant::now();
    let duracion = final_instant.elapsed(); // Retorna un Duration
    
    println!("La tarea tardó: {:?}", duracion);

    // 2. Uso de SystemTime y Timestamp de Unix
    let ahora_sistema = SystemTime::now();
    match ahora_sistema.duration_since(SystemTime::UNIX_EPOCH) {
        Ok(timestamp) => println!("Timestamp Unix: {} segundos", timestamp.as_secs()),
        Err(_) => println!("El reloj del sistema es anterior a la época Unix"),
    }

    // 3. Operaciones con Duration
    let tiempo_base = Duration::from_secs(2);
    let extra = Duration::from_millis(500);
    
    // Suma simple
    let tiempo_total = tiempo_base + extra;
    println!("Tiempo total sumado: {:?}", tiempo_total);

    // Operación segura para evitar desbordamiento (overflow)
    let limite = Duration::MAX;
    let suma_segura = tiempo_base.checked_add(limite);
    
    match suma_segura {
        Some(t) => println!("Suma segura: {:?}", t),
        None => println!("Error: La suma superó el límite máximo de Duration"),
    }
    
    println!("Valor cero: {:?}", Duration::ZERO);
}

Explicación del Código

  • inicio: Es una instancia de Instant que captura el momento exacto antes de iniciar la tarea.
  • final_instant: Captura el momento actual mediante Instant::now() tras la ejecución de thread::sleep.
  • duracion: Es un objeto de tipo Duration obtenido mediante el método elapsed() sobre final_instant. Representa el intervalo transcurrido.
  • ahora_sistema: Una instancia de SystemTime que representa la hora actual del sistema operativo.
  • timestamp: Es el Duration resultante de calcular la diferencia entre ahora_sistema y SystemTime::UNIX_EPOCH. Se usa as_secs() para obtener el valor entero.
  • tiempo_base: Un Duration creado a partir de 2 segundos mediante from_secs.
  • extra: Un Duration de 500 milisegundos.
  • tiempo_total: Resultado de la suma aritmética entre tiempo_base y extra.
  • suma_segura: Utiliza el método checked_add para intentar sumar tiempo_base con Duration::MAX. Como esta suma desbordaría el límite máximo permitido, el método devuelve None.

124