| Crates.io | switchy_time |
| lib.rs | switchy_time |
| version | 0.1.4 |
| created_at | 2025-05-07 20:39:34.308537+00 |
| updated_at | 2025-07-21 19:15:49.095416+00 |
| description | Switchy Time package |
| homepage | |
| repository | https://github.com/MoosicBox/MoosicBox |
| max_upload_size | |
| id | 1664441 |
| size | 17,138 |
A simple time abstraction library providing unified time access with support for both standard system time and simulated time for testing.
now() function that works with different time backendsAdd this to your Cargo.toml:
[dependencies]
moosicbox_time = "0.1.1"
# Choose your backend
moosicbox_time = { version = "0.1.1", features = ["std"] }
# or for testing
moosicbox_time = { version = "0.1.1", features = ["simulator"] }
use moosicbox_time::now;
use std::time::SystemTime;
fn main() {
let current_time: SystemTime = now();
println!("Current time: {:?}", current_time);
// Time behaves like SystemTime::now() in standard mode
let duration_since_epoch = current_time
.duration_since(std::time::UNIX_EPOCH)
.unwrap();
println!("Seconds since epoch: {}", duration_since_epoch.as_secs());
}
#[cfg(feature = "simulator")]
use moosicbox_time::simulator::{now, reset_step, next_step, set_step, current_step};
#[cfg(feature = "simulator")]
fn test_with_simulated_time() {
// Reset to initial state
reset_step();
let time1 = now();
println!("Step 0 time: {:?}", time1);
// Advance time by one step
next_step();
let time2 = now();
println!("Step 1 time: {:?}", time2);
// Jump to specific step
set_step(100);
let time3 = now();
println!("Step 100 time: {:?}", time3);
// Check current step
println!("Current step: {}", current_step());
}
#[cfg(feature = "simulator")]
use moosicbox_time::simulator::{
reset_epoch_offset, epoch_offset,
reset_step_multiplier, step_multiplier
};
#[cfg(feature = "simulator")]
fn configure_simulation() {
// Reset epoch offset (randomized base time)
reset_epoch_offset();
println!("Epoch offset: {}", epoch_offset());
// Reset step multiplier (time advancement per step)
reset_step_multiplier();
println!("Step multiplier: {}", step_multiplier());
// Environment variables can control these values:
// SIMULATOR_EPOCH_OFFSET - sets the epoch offset
// SIMULATOR_STEP_MULTIPLIER - sets the step multiplier
}
#[cfg(feature = "simulator")]
use moosicbox_time::simulator::{with_real_time, now};
#[cfg(feature = "simulator")]
fn use_real_time_temporarily() {
// In simulator mode, get simulated time
let simulated_time = now();
println!("Simulated time: {:?}", simulated_time);
// Temporarily use real system time
let real_time = with_real_time(|| {
now() // This returns actual SystemTime::now()
});
println!("Real time: {:?}", real_time);
// Back to simulated time
let simulated_again = now();
println!("Simulated time again: {:?}", simulated_again);
}
#[cfg(feature = "simulator")]
use moosicbox_time::{now, simulator::{reset_step, next_step, set_step}};
use std::time::Duration;
#[cfg(feature = "simulator")]
struct TimestampedEvent {
timestamp: std::time::SystemTime,
data: String,
}
#[cfg(feature = "simulator")]
fn test_time_dependent_logic() {
reset_step();
let mut events = Vec::new();
// Create events at different time steps
for i in 0..5 {
set_step(i * 1000); // Each step is 1000 multiplier units apart
events.push(TimestampedEvent {
timestamp: now(),
data: format!("Event {}", i),
});
}
// Verify event ordering
for (i, event) in events.iter().enumerate() {
println!("Event {}: {} at {:?}", i, event.data, event.timestamp);
if i > 0 {
let duration = event.timestamp
.duration_since(events[i-1].timestamp)
.unwrap();
println!(" Time since previous: {:?}", duration);
}
}
}
The simulator can be configured via environment variables:
# Set a specific epoch offset (milliseconds since Unix epoch)
export SIMULATOR_EPOCH_OFFSET=1640995200000
# Set step multiplier (milliseconds per step)
export SIMULATOR_STEP_MULTIPLIER=1000
# Run your application
cargo run --features simulator
now() - Returns SystemTime from appropriate backendstd feature)std::time::SystemTime::now() directlysimulator feature)now() - Returns simulated time based on current stepreset_step() - Reset step counter to 0next_step() - Advance to next step and return new step numberset_step(step) - Set specific step numbercurrent_step() - Get current step numberreset_epoch_offset() - Generate new random epoch offsetepoch_offset() - Get current epoch offsetreset_step_multiplier() - Generate new random step multiplierstep_multiplier() - Get current step multiplierwith_real_time(f) - Execute function with real system timeIn simulator mode, time is calculated as:
time = UNIX_EPOCH + Duration::from_millis(epoch_offset + (step * step_multiplier))
std - Enable standard system time backendsimulator - Enable time simulation backendstd feature for normal time operationssimulator feature for deterministic time testingsimulator feature to test time-dependent logicEach thread maintains its own simulation state (step, epoch offset, step multiplier) using thread-local storage.