| Crates.io | prism3-clock |
| lib.rs | prism3-clock |
| version | 0.1.0 |
| created_at | 2025-10-18 18:41:11.051558+00 |
| updated_at | 2025-10-18 18:41:11.051558+00 |
| description | Thread-safe clock abstractions for Rust: monotonic clocks, mock testing, high-precision time meters, and timezone support |
| homepage | https://github.com/3-prism/prism3-rust-clock |
| repository | https://github.com/3-prism/prism3-rust-clock |
| max_upload_size | |
| id | 1889517 |
| size | 238,077 |
Thread-safe clock abstractions for Rust with monotonic and mock implementations.
Prism3 Clock provides a flexible and type-safe clock abstraction system for Rust applications. It offers robust, thread-safe clock implementations with support for basic time access, high-precision measurements, timezone handling, monotonic time, and testing support.
Send + Syncchrono-tz for comprehensive timezone databaseAdd this to your Cargo.toml:
[dependencies]
prism3-clock = "0.1.0"
use prism3_clock::{Clock, SystemClock};
let clock = SystemClock::new();
let timestamp = clock.millis();
let time = clock.time();
println!("Current time: {}", time);
use prism3_clock::{Clock, ZonedClock, SystemClock, Zoned};
use chrono_tz::Asia::Shanghai;
let clock = Zoned::new(SystemClock::new(), Shanghai);
let local = clock.local_time();
println!("Local time in Shanghai: {}", local);
use prism3_clock::{Clock, MonotonicClock};
use std::thread;
use std::time::Duration;
let clock = MonotonicClock::new();
let start = clock.millis();
thread::sleep(Duration::from_millis(100));
let elapsed = clock.millis() - start;
println!("Elapsed: {} ms", elapsed);
use prism3_clock::{Clock, ControllableClock, MockClock};
use chrono::{DateTime, Duration, Utc};
let clock = MockClock::new();
// Set to a specific time
let fixed_time = DateTime::parse_from_rfc3339(
"2024-01-01T00:00:00Z"
).unwrap().with_timezone(&Utc);
clock.set_time(fixed_time);
assert_eq!(clock.time(), fixed_time);
// Advance time
clock.add_duration(Duration::hours(1));
assert_eq!(clock.time(), fixed_time + Duration::hours(1));
use prism3_clock::{NanoClock, NanoMonotonicClock};
let clock = NanoMonotonicClock::new();
let start = clock.nanos();
// Perform some operation
for _ in 0..1000 {
// Some work
}
let elapsed = clock.nanos() - start;
println!("Elapsed: {} ns", elapsed);
use prism3_clock::meter::TimeMeter;
use std::thread;
use std::time::Duration;
let mut meter = TimeMeter::new();
meter.start();
thread::sleep(Duration::from_millis(100));
meter.stop();
println!("Elapsed: {}", meter.readable_duration());
use prism3_clock::meter::NanoTimeMeter;
let mut meter = NanoTimeMeter::new();
meter.start();
// Perform some operation
for _ in 0..1000 {
// Some work
}
meter.stop();
println!("Elapsed: {} ns", meter.nanos());
println!("Readable: {}", meter.readable_duration());
use prism3_clock::meter::TimeMeter;
use std::thread;
use std::time::Duration;
let mut meter = TimeMeter::new();
meter.start();
// Process 1000 items
for _ in 0..1000 {
thread::sleep(Duration::from_micros(100));
}
meter.stop();
println!("Processed 1000 items in {}", meter.readable_duration());
println!("Speed: {}", meter.readable_speed(1000));
The crate is built around several orthogonal traits:
This design follows the Interface Segregation Principle, ensuring that implementations only need to provide the features they actually support.
std::time::Instant (monotonically increasing)std::time::Instant with nanosecond precisionMonotonicClockArc<Mutex<>>MonotonicClock for stabilityClock implementationA millisecond-precision time meter for measuring elapsed time with the following features:
Clock traitMockClock for deterministic testingExample output formats:
123 ms - Less than 1 second1.23 s - 1-60 seconds1 m 23.45 s - More than 1 minuteA nanosecond-precision time meter with features similar to TimeMeter:
NanoClock traitExample output formats:
123 ns - Less than 1 microsecond123.45 ΞΌs - 1-1000 microseconds123.45 ms - 1-1000 milliseconds1.23 s - 1-60 seconds1 m 23.45 s - More than 1 minuteThe core Clock trait provides:
millis() - Returns current time in milliseconds since Unix epochtime() - Returns current time as DateTime<Utc>Extension trait for high-precision clocks:
nanos() - Returns current time in nanoseconds since Unix epochnano_time() - Returns high-precision DateTime<Utc>Extension trait for timezone support:
timezone() - Returns the clock's timezonelocal_time() - Returns current time in the clock's timezonelocal_time_in(tz) - Returns current time in specified timezoneExtension trait for controllable clocks (testing):
set_time(instant) - Sets the clock to a specific timeadd_duration(duration) - Advances the clock by a durationreset() - Resets the clock to initial stateThe crate follows the Interface Segregation Principle by providing separate traits for different capabilities:
NanoClock is separateZonedClock is separateControllableClock is separateThis allows implementations to provide only the features they need, keeping the API clean and focused.
Each trait and type has one clear purpose:
Clock - Provide UTC timeNanoClock - Provide high-precision timeZonedClock - Provide timezone conversionControllableClock - Provide time control for testingFunctionality is extended through wrappers rather than inheritance:
Zoned<C> wraps any Clock to add timezone supportClock implementation via genericsThe design ensures you only pay for what you use:
SystemClock and MonotonicClock are zero-sized or minimal overheadThis project maintains comprehensive test coverage with detailed validation of all functionality.
# Run all tests
cargo test
# Run with coverage report
./coverage.sh
# Generate text format report
./coverage.sh text
# Run CI checks (tests, lints, formatting)
./ci-check.sh
use prism3_clock::meter::TimeMeter;
let mut meter = TimeMeter::new();
meter.start();
// Perform operation
process_data();
meter.stop();
log::info!("Processing took: {}", meter.readable_duration());
use prism3_clock::{Clock, MonotonicClock};
use std::time::Duration;
let clock = MonotonicClock::new();
let deadline = clock.millis() + 5000; // 5 seconds from now
while clock.millis() < deadline {
if try_operation() {
break;
}
}
use prism3_clock::{Clock, ControllableClock, MockClock};
use chrono::Duration;
#[test]
fn test_expiration() {
let clock = MockClock::new();
let item = Item::new(clock.clone());
// Fast-forward 1 hour
clock.add_duration(Duration::hours(1));
assert!(item.is_expired());
}
use prism3_clock::meter::NanoTimeMeter;
let mut meter = NanoTimeMeter::new();
meter.start();
for _ in 0..10000 {
expensive_operation();
}
meter.stop();
println!("Average time per operation: {} ns", meter.nanos() / 10000);
Copyright (c) 2025 3-Prism Co. Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
See LICENSE for the full license text.
Contributions are welcome! Please feel free to submit a Pull Request.
Haixing Hu - 3-Prism Co. Ltd.
For more information about the Prism3 ecosystem, visit our GitHub homepage.