nanotime 0.1.1

A minimal, zero-dependency time utility crate for Rust CLI applications
Documentation
  • Coverage
  • 100%
    37 out of 37 items documented2 out of 37 items with examples
  • Size
  • Source code size: 70.78 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.38 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 12s Average build duration of successful builds.
  • all releases: 13s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • anthonysgro/nanotime
    2 1 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • anthonysgro

⏱ nanotime

Crates.io Docs.rs

A minimal, zero-dependency time utility crate for Rust CLI applications.

Part of the nano crate family — minimal, zero-dependency building blocks for CLI apps in Rust:

Local and UTC time retrieval, nanosecond-precision timestamps, human-readable formatting, relative time strings, and lightweight elapsed duration measurement — no heavy crates, no transitive dependencies.

Motivation

Most Rust time crates (like chrono or time) are feature-rich but pull in dependencies or offer far more than you need. If all you want is the current time and a simple way to measure durations, those crates are overkill.

nanotime solves this by providing the essentials and nothing more:

  • Zero external dependencies (only std + raw FFI)
  • Nanosecond-precision timestamps with millisecond and microsecond accessors
  • Local time via platform FFI (clock_gettime on Unix, GetLocalTime on Windows)
  • UTC time via SystemTime + manual calendar arithmetic
  • Elapsed duration measurement via std::time::Instant
  • Human-readable formatting out of the box
  • Validated constructor — no invalid dates
  • Implements Ord, Hash, Eq, Clone, Copy, Debug

Comparison

nanotime is intentionally minimal. If you need timezones, parsing, arithmetic, or no_std, use chrono or time — they're great crates.

nanotime is for when you just want to know what time it is and how long something took.

Feature nanotime chrono time
Zero dependencies
Single file
Clean build (release) ~0.12s ~1.6s ~1.6s
Current local time
Current UTC time
Nanosecond precision
Elapsed measurement
Relative time ("3s ago")
Human-readable display
Timezone conversion
Date/time parsing
Date/time arithmetic
no_std support

Quick Start

[dependencies]
nanotime = "0.1.0"
use nanotime::{NanoTime, Elapsed};

fn main() {
    let now = NanoTime::now();
    println!("Local time: {}", now);            // "14:32:07.042"
    println!("Local datetime: {}", now.datetime()); // "2026-02-22 14:32:07.042"

    let utc = NanoTime::now_utc();
    println!("UTC: {}", utc.datetime());

    // Relative time
    let past = NanoTime::new(2025, 1, 1, 0, 0, 0, 0).unwrap();
    println!("{}", past.ago()); // e.g. "419d ago"

    // Elapsed timer
    let timer = Elapsed::start();
    // ... do some work ...
    println!("Took {}", timer); // "42ms" or "1.23s"
}

Usage

Get the current time

use nanotime::NanoTime;

let local = NanoTime::now();       // local time via platform FFI
let utc = NanoTime::now_utc();     // UTC via SystemTime

println!("{}", local);             // "14:32:07.042"
println!("{}", local.date());      // "2026-02-22"
println!("{}", local.datetime());  // "2026-02-22 14:32:07.042"

Create timestamps

use nanotime::NanoTime;

// Validated constructor (returns None for invalid dates)
let t = NanoTime::new(2026, 2, 22, 14, 30, 0, 500_000_000).unwrap();

// From epoch values
let from_secs = NanoTime::from_epoch(1_000_000_000);
let from_ms = NanoTime::from_epoch_ms(1_000_000_000_042);
let from_us = NanoTime::from_epoch_us(1_000_000_000_042_000);
let from_ns = NanoTime::from_epoch_nanos(1_000_000_000_042_000_000);

// Invalid dates return None
assert!(NanoTime::new(2025, 2, 29, 0, 0, 0, 0).is_none()); // not a leap year
assert!(NanoTime::new(2026, 13, 1, 0, 0, 0, 0).is_none());  // invalid month

Access fields

use nanotime::NanoTime;

let now = NanoTime::now();
println!("Year: {}, Month: {}, Day: {}", now.year(), now.month(), now.day());
println!("{}:{}:{}", now.hour(), now.minute(), now.second());

// Sub-second accessors (derived from nanosecond field)
println!("Nanoseconds: {}", now.nanosecond());   // 0–999,999,999
println!("Microseconds: {}", now.microsecond());  // 0–999,999
println!("Milliseconds: {}", now.millisecond());  // 0–999

Formatting

use nanotime::NanoTime;

let t = NanoTime::new(2026, 2, 22, 14, 30, 5, 123_456_789).unwrap();

// Default formatting includes milliseconds
println!("{}", t);              // "14:30:05.123"
println!("{}", t.date());       // "2026-02-22"
println!("{}", t.datetime());   // "2026-02-22 14:30:05.123"

// Flexible precision with datetime_fmt (0–9 fractional digits)
println!("{}", t.datetime_fmt(0)); // "2026-02-22 14:30:05"
println!("{}", t.datetime_fmt(3)); // "2026-02-22 14:30:05.123"
println!("{}", t.datetime_fmt(6)); // "2026-02-22 14:30:05.123456"
println!("{}", t.datetime_fmt(9)); // "2026-02-22 14:30:05.123456789"

Epoch conversions

use nanotime::NanoTime;

let t = NanoTime::new(2026, 2, 22, 14, 30, 0, 500_000_000).unwrap();

// Convert to epoch at any granularity
let secs = t.to_epoch_secs();    // u64
let ms = t.to_epoch_ms();        // u64
let us = t.to_epoch_us();        // u128
let nanos = t.to_epoch_nanos();  // u128

Time differences

use nanotime::NanoTime;

let a = NanoTime::from_epoch(1_000_100);
let b = NanoTime::from_epoch(1_000_000);

// At any granularity
println!("{}", a.diff_secs(&b));   //  100
println!("{}", a.diff_ms(&b));     //  100000
println!("{}", a.diff_us(&b));     //  100000000
println!("{}", a.diff_nanos(&b));  //  100000000000

Relative time

use nanotime::NanoTime;

let past = NanoTime::new(2025, 1, 1, 0, 0, 0, 0).unwrap();
println!("{}", past.ago()); // e.g. "419d ago"

let a = NanoTime::new(2026, 2, 22, 12, 0, 0, 0).unwrap();
let b = NanoTime::new(2026, 2, 22, 12, 5, 30, 0).unwrap();
println!("{}", a.relative_to(&b)); // "5m ago"
println!("{}", b.relative_to(&a)); // "in 5m"

Buckets: just now, Xs, Xm, Xh, Xd — with "ago" or "in" prefix/suffix for direction.

Measure elapsed time

use nanotime::Elapsed;

let timer = Elapsed::start();

// ... do some work ...

println!("Elapsed: {}", timer);                   // "42ms" or "1.23s"
println!("Seconds: {:.3}", timer.elapsed_secs()); // "0.042"
println!("Milliseconds: {}", timer.elapsed_ms()); // "42"

The Display impl automatically picks the right unit:

  • Under 1 second: Xms (e.g. 450ms)
  • 1 second or more: X.XXs (e.g. 1.23s)

API Reference

NanoTime

Constructors

Method Returns Description
NanoTime::new(year, month, day, hour, minute, second, nanosecond) Option<NanoTime> Validated constructor. Returns None for invalid dates.
NanoTime::now() NanoTime Current local time via platform FFI
NanoTime::now_utc() NanoTime Current UTC time via SystemTime
NanoTime::from_epoch(secs) NanoTime From Unix epoch seconds
NanoTime::from_epoch_ms(ms) NanoTime From Unix epoch milliseconds
NanoTime::from_epoch_us(us) NanoTime From Unix epoch microseconds
NanoTime::from_epoch_nanos(nanos) NanoTime From Unix epoch nanoseconds

Getters

Method Returns Description
.year() u16 Calendar year
.month() u8 Month (1–12)
.day() u8 Day of month (1–31)
.hour() u8 Hour (0–23)
.minute() u8 Minute (0–59)
.second() u8 Second (0–59)
.nanosecond() u32 Nanosecond (0–999,999,999)
.millisecond() u16 Derived: nanosecond / 1,000,000
.microsecond() u32 Derived: nanosecond / 1,000

Formatting

Method Returns Example
Display (format!) 14:30:05.123
.date() String 2026-02-22
.datetime() String 2026-02-22 14:30:05.123
.datetime_fmt(precision) String 2026-02-22 14:30:05.123456 (precision=6)

Epoch Conversions

Method Returns Description
.to_epoch_secs() u64 Unix epoch seconds
.to_epoch_ms() u64 Unix epoch milliseconds
.to_epoch_us() u128 Unix epoch microseconds
.to_epoch_nanos() u128 Unix epoch nanoseconds

Differences

Method Returns Description
.diff_secs(&other) i64 Signed difference in seconds
.diff_ms(&other) i64 Signed difference in milliseconds
.diff_us(&other) i128 Signed difference in microseconds
.diff_nanos(&other) i128 Signed difference in nanoseconds

Relative Time

Method Returns Description
.relative_to(&other) String e.g. "3s ago", "in 2h"
.ago() String Relative to now (UTC)

Elapsed

Method Returns Description
Elapsed::start() Elapsed Capture current instant
.elapsed_secs() f64 Elapsed seconds
.elapsed_ms() u128 Elapsed milliseconds
.elapsed_us() u128 Elapsed microseconds
.elapsed_nanos() u128 Elapsed nanoseconds
Display Xms or X.XXs

Contributing

Contributions are welcome. To get started:

  1. Fork the repository
  2. Create a feature branch (git checkout -b my-feature)
  3. Make your changes
  4. Run the tests: cargo test
  5. Submit a pull request

Please keep changes minimal and focused. This crate's goal is to stay small and dependency-free.

License

This project is licensed under the MIT License.