#date-time #unix-timestamp #date-format #time-formatting #iso-8601 #strftime #date-time-format #date-time-formatting

no-std time-format

A lightweight library for formatting Unix timestamps with millisecond precision in UTC and local time

8 stable releases

1.2.1 May 20, 2025
1.1.2 Feb 14, 2022
1.1.1 Jan 19, 2022
1.1.0 Nov 9, 2021
1.0.2 Nov 9, 2021

#62 in Date and time

26 downloads per month
Used in etchdns

MIT license

45KB
422 lines

time-format

Crates.io Documentation License: MIT

A lightweight, zero-dependency Rust crate for formatting Unix timestamps in both UTC and local time, with millisecond precision.

Features

  • 🚀 Zero dependencies - No external crates needed
  • 🌐 Multiple timezones - Support for both UTC and local time zones
  • ⏱️ Millisecond precision - High-resolution timestamp formatting
  • 🧩 Component access - Split timestamps into their individual components
  • 📅 Standard formats - Built-in support for ISO 8601, RFC 3339, RFC 2822, and more
  • 🔄 Custom formatting - Flexible formatting using C's strftime patterns
  • Performance - Direct FFI bindings to system time functions

Why time-format?

Simple things should be simple.

When you just need to format a timestamp in a standardized way like ISO 8601 or get time components, you shouldn't need to pull in complex dependencies, understand type conversion hierarchies, or deal with feature flags.

time-format excels at:

  • Minimalism: Zero dependencies means faster builds and smaller binaries
  • Simplicity: Clear and intuitive API with straightforward error handling
  • Performance: Thin wrapper over system time functions for minimal overhead
  • Common formats: Built-in support for the most widely used date formats

It's the ideal choice when you just need timestamp formatting without the complexity of full-featured time libraries.

Installation

Add to your Cargo.toml:

[dependencies]
time-format = "1.2.0"

Basic Usage

Getting the Current Time

// Get current time in seconds
let ts = time_format::now().unwrap();

// Get current time with millisecond precision
let ts_ms = time_format::now_ms().unwrap();

Converting from SystemTime

use std::time::SystemTime;

// Convert a SystemTime to a TimeStamp (seconds)
let system_time = SystemTime::now();
let ts = time_format::from_system_time(system_time).unwrap();

// Convert a SystemTime to a TimeStampMs (with millisecond precision)
let ts_ms = time_format::from_system_time_ms(system_time).unwrap();

Splitting a Timestamp into Components

// Get components in UTC
let ts = time_format::now().unwrap();
let components = time_format::components_utc(ts).unwrap();
println!("Current hour: {}", components.hour);

// Available components:
// - sec (0-59)
// - min (0-59)
// - hour (0-23)
// - month_day (1-31)
// - month (1-12) - January is 1, December is 12
// - year (e.g., 2025)
// - week_day (0-6) - Sunday is 0, Saturday is 6
// - year_day (0-365)

// Get components in local time
let local_components = time_format::components_local(ts).unwrap();

Formatting a Timestamp

UTC Time

let ts = time_format::now().unwrap();

// Basic date formatting
let date = time_format::strftime_utc("%Y-%m-%d", ts).unwrap();
// Example: "2025-05-20"

// Time formatting
let time = time_format::strftime_utc("%H:%M:%S", ts).unwrap();
// Example: "14:30:45"

// Combined date and time
let datetime = time_format::strftime_utc("%Y-%m-%d %H:%M:%S", ts).unwrap();
// Example: "2025-05-20 14:30:45"

// Custom format
let custom = time_format::strftime_utc("%a, %d %b %Y %T %Z", ts).unwrap();
// Example: "Tue, 20 May 2025 14:30:45 UTC"

Local Time

let ts = time_format::now().unwrap();

// Local time with timezone name
let local_time = time_format::strftime_local("%Y-%m-%d %H:%M:%S %Z", ts).unwrap();
// Example: "2025-05-20 09:30:45 PDT"

Millisecond Precision

let ts_ms = time_format::now_ms().unwrap();

// Format with milliseconds in UTC
let precise_time = time_format::strftime_ms_utc("%Y-%m-%d %H:%M:%S.{ms}", ts_ms).unwrap();
// Example: "2025-05-20 14:30:45.123"

// Format with milliseconds in local time
let precise_local = time_format::strftime_ms_local("%Y-%m-%d %H:%M:%S.{ms} %Z", ts_ms).unwrap();
// Example: "2025-05-20 09:30:45.123 PDT"

ISO 8601 Formatting

Format timestamps according to ISO 8601 standard:

let ts = time_format::now().unwrap();
let ts_ms = time_format::now_ms().unwrap();

// ISO 8601 in UTC
let iso8601 = time_format::format_iso8601_utc(ts).unwrap();
// Example: "2025-05-20T14:30:45Z"

// ISO 8601 with milliseconds in UTC
let iso8601_ms = time_format::format_iso8601_ms_utc(ts_ms).unwrap();
// Example: "2025-05-20T14:30:45.123Z"

// ISO 8601 in local timezone
let iso8601_local = time_format::format_iso8601_local(ts).unwrap();
// Example: "2025-05-20T09:30:45-05:00"

// ISO 8601 with milliseconds in local timezone
let iso8601_ms_local = time_format::format_iso8601_ms_local(ts_ms).unwrap();
// Example: "2025-05-20T09:30:45.123-05:00"

Common Date Formats

The crate provides convenient formatting for common date formats:

let ts = time_format::now().unwrap();
let ts_ms = time_format::now_ms().unwrap();

// RFC 3339 (similar to ISO 8601)
let rfc3339 = time_format::format_common_utc(ts, time_format::DateFormat::RFC3339).unwrap();
// Example: "2025-05-20T14:30:45Z"

// RFC 2822 format (email format)
let rfc2822 = time_format::format_common_utc(ts, time_format::DateFormat::RFC2822).unwrap();
// Example: "Tue, 20 May 2025 14:30:45 +0000"

// HTTP date format (RFC 7231)
let http_date = time_format::format_common_utc(ts, time_format::DateFormat::HTTP).unwrap();
// Example: "Tue, 20 May 2025 14:30:45 GMT"

// SQL date format
let sql_format = time_format::format_common_utc(ts, time_format::DateFormat::SQL).unwrap();
// Example: "2025-05-20 14:30:45"

// US date format
let us_format = time_format::format_common_local(ts, time_format::DateFormat::US).unwrap();
// Example: "05/20/2025 02:30:45 PM"

// European date format
let eu_format = time_format::format_common_local(ts, time_format::DateFormat::European).unwrap();
// Example: "20/05/2025 14:30:45"

// With millisecond precision
let rfc3339_ms = time_format::format_common_ms_utc(ts_ms, time_format::DateFormat::RFC3339).unwrap();
// Example: "2025-05-20T14:30:45.123Z"

// Custom format
let custom = time_format::format_common_utc(ts, time_format::DateFormat::Custom("%Y/%m/%d")).unwrap();
// Example: "2025/05/20"

Available format types:

  • RFC3339: ISO 8601-like format
  • RFC2822: Email date format
  • HTTP: Web standard date format
  • SQL: SQL database format
  • US: US style date format (MM/DD/YYYY)
  • European: European style date format (DD/MM/YYYY)
  • ShortDate: Short date (MM/DD/YY)
  • LongDate: Long date with full month and day names
  • ShortTime: Hours and minutes
  • LongTime: Hours, minutes, and seconds
  • DateTime: ISO-like date and time
  • Custom: Custom format string

Common Format Directives

Directive Description Example
%Y Year (4 digits) 2025
%m Month (01-12) 05
%d Day of month (01-31) 20
%H Hour (00-23) 14
%M Minute (00-59) 30
%S Second (00-59) 45
%a Abbreviated weekday Tue
%A Full weekday Tuesday
%b Abbreviated month May
%B Full month May
%c Locale date and time Tue May 20 14:30:45 2025
%Z Timezone name UTC, PDT, etc.
%z Timezone offset +0000, -0500
{ms} Milliseconds (custom extension) 123

Comparison with Other Time Libraries

Feature time-format chrono time
Dependencies None Multiple Multiple
ISO 8601
RFC 2822/3339
Milliseconds
Local timezone
Custom formats
Binary size impact Very Small Larger Medium
Compile time Fast Slower Medium

time-format is designed to be a lightweight alternative when you only need basic timestamp formatting capabilities without pulling in additional dependencies.

  • coarsetime - A minimal crate to get timestamps and perform basic operations on them
  • chrono - Complete date and time library with calendar feature support
  • time - A comprehensive time library with timezone database support

Examples

Working with Web APIs

use time_format::{format_iso8601_utc, now};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Get current time
    let current_time = now()?;

    // Format as ISO 8601 for API request
    let timestamp = format_iso8601_utc(current_time)?;

    println!("API Request time: {}", timestamp);
    // Example output: "2025-05-20T14:30:45Z"

    // Now you can use this timestamp in your API requests
    // let response = make_api_request(timestamp);

    Ok(())
}

Converting from SystemTime in Network Applications

use std::time::{SystemTime, Duration};
use time_format::{from_system_time_ms, format_iso8601_ms_utc, strftime_ms_utc};

// Example of tracking network response times
fn measure_network_response() -> Result<(), Box<dyn std::error::Error>> {
    // Record start time
    let start_time = SystemTime::now();

    // Simulate a network request
    // In a real application, this would be an actual HTTP request
    std::thread::sleep(Duration::from_millis(237));

    // Record end time
    let end_time = SystemTime::now();

    // Convert to TimeStampMs
    let start_ts = from_system_time_ms(start_time)?;
    let end_ts = from_system_time_ms(end_time)?;

    // Calculate duration
    let duration_ms = end_ts.total_milliseconds() - start_ts.total_milliseconds();

    // Log with ISO 8601 timestamps
    println!("Network request at: {}", format_iso8601_ms_utc(start_ts)?);
    println!("Response received at: {}", format_iso8601_ms_utc(end_ts)?);
    println!("Request took: {}ms", duration_ms);

    // Custom formatting for logging
    let log_line = format!(
        "[{}] Request completed in {}ms",
        strftime_ms_utc("%Y-%m-%d %H:%M:%S.{ms}", end_ts)?,
        duration_ms
    );
    println!("{}", log_line);
    // Example: "[2025-05-20 14:30:45.123] Request completed in 237ms"

    Ok(())
}

Logging with Timestamps

use time_format::{DateFormat, format_common_ms_local, now_ms};

fn log_message(level: &str, message: &str) -> Result<(), Box<dyn std::error::Error>> {
    // Get current time with millisecond precision
    let current_time = now_ms()?;

    // Format with milliseconds for logging
    let timestamp = format_common_ms_local(current_time, DateFormat::DateTime)?;

    println!("[{}] {} - {}", timestamp, level, message);
    // Example output: "[2025-05-20 09:30:45.123] INFO - Application started"

    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    log_message("INFO", "Application started")?;
    log_message("DEBUG", "Configuration loaded")?;

    Ok(())
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License.


Note: This crate uses FFI bindings to C's time functions. It's designed to be lightweight and efficient, but it does not include a timezone database. For applications requiring extensive timezone handling, consider chrono or time.

No runtime deps

Features