7 releases
Uses new Rust 2024
| 0.3.0 | Dec 10, 2025 |
|---|---|
| 0.2.3 | Sep 17, 2025 |
| 0.1.2 | Sep 11, 2025 |
#85 in Date and time
Used in 2 crates
(via nonblocking-logger)
125KB
2.5K
SLoC
simple-datetime-rs
A high-performance, lightweight date and time library for Rust that provides dramatically faster parsing and memory-efficient operations for common date/time tasks.
ðĄïļ Safety & Reliability
- 100% Pure Rust - No unsafe code blocks, ensuring memory safety
- Zero Dependencies - No external dependencies for native targets (only
wasm-bindgenfor WASM, optionalserdefor serialization) - Memory Safe - All operations are guaranteed safe by Rust's ownership system
- No Panics - Graceful error handling with comprehensive validation
- Cross-Platform - Works identically on all supported platforms
Performance Advantages
Parsing Performance â
| Operation | simple-datetime-rs | chrono | Performance Gain |
|---|---|---|---|
| Date Parsing | 6.13 ns | 105.41 ns | ð simple-datetime-rs 17.2x faster |
| Time Parsing | 7.19 ns | 89.11 ns | ð simple-datetime-rs 12.4x faster |
| DateTime Parsing | 43.67 ns | 58.70 ns | ð simple-datetime-rs 1.3x faster |
Memory Efficiency
| Operation | simple-datetime-rs | chrono | Memory Advantage |
|---|---|---|---|
| 1000 Date Objects | 1.29 Ξs | N/A | simple-datetime-rs only |
| 1000 Time Objects | 1.53 Ξs | N/A | simple-datetime-rs only |
| 1000 DateTime Objects | 3.30 Ξs | 42.43 Ξs | simple-datetime-rs 12.9x more efficient |
Critical Path Performance
| Workflow | simple-datetime-rs | chrono | Performance Gain |
|---|---|---|---|
| Complete Workflow | 610.91 ns | 763.94 ns | simple-datetime-rs 1.25x faster |
ðĻ Chrono-Compatible Formatting â
Format Strings Just Like Chrono
use simple_datetime_rs::{DateTime, Format};
let now = DateTime::now();
println!("{}", now.format("%Y-%m-%d %H:%M:%S")?); // "2025-09-17 07:53:14"
println!("{}", now.format("%A, %B %d, %Y at %I:%M %p")?); // "Wednesday, September 17, 2025 at 07:53 AM"
println!("{}", now.format("%+")?); // "2025-09-17T07:53:14Z" (ISO 8601)
Comprehensive Format Specifiers
- Date:
%Y(year),%m(month),%d(day),%B(month name),%A(weekday) - Time:
%H(24-hour),%I(12-hour),%M(minute),%S(second),%f(microsecond),%p(AM/PM) - Timezone:
%z(offset),%:z(offset with colon) - Combined:
%D(MM/DD/YY),%T(HH:MM:SS),%F(YYYY-MM-DD),%+(ISO 8601)
Works with All Types
let date = Date::new(2023, 6, 15);
let time = Time::new(14, 30, 45);
let datetime = DateTime::new(date, time, 0);
println!("{}", date.format("%A, %B %d, %Y")?); // "Thursday, June 15, 2023"
println!("{}", time.format("%I:%M %p")?); // "02:30 PM"
println!("{}", datetime.format("%Y-%m-%d %H:%M:%S")?); // "2023-06-15 14:30:45"
Key Advantages
1. Superior Memory Efficiency
- 12.9x more memory efficient than chrono for DateTime operations
- Minimal memory footprint for bulk operations
- Zero-allocation design for many operations
2. Dramatically Faster String Parsing ð
- 17.2x faster date parsing than chrono
- 12.4x faster time parsing than chrono
- 1.3x faster datetime parsing than chrono
- Zero-allocation parsing algorithms for maximum performance
4. Lightweight Design
- Zero dependencies for native targets (only
wasm-bindgenfor WASM) - Small binary size impact
- Fast compilation times
- Pure Rust implementation with no unsafe code
5. WASM Compatibility
- Built-in WebAssembly support
- No external dependencies for WASM builds
- Optimized for web applications
Unique Features
ðŊ Advanced Date Operations
Year Day Calculation
let date = Date::new(2023, 6, 15);
let day_of_year = date.year_day(); // 166 (June 15th is the 166th day)
let days_remaining = date.days_to_next_year(); // 199 days left in 2023
Why it's unique: Most libraries don't provide direct year day calculation or days remaining functionality.
Quarter Calculation
let q1 = Date::new(2023, 2, 15).quarter(); // 1
let q2 = Date::new(2023, 5, 15).quarter(); // 2
let q3 = Date::new(2023, 8, 15).quarter(); // 3
let q4 = Date::new(2023, 11, 15).quarter(); // 4
Why it's unique: Built-in quarter calculation for business applications.
Month Boundary Operations
let date = Date::new(2023, 2, 28);
let is_last_day = date.is_month_last_day(); // true
let last_day = date.month_last_day(); // 2023-02-28
let leap_date = Date::new(2024, 2, 28);
let is_last_day_leap = leap_date.is_month_last_day(); // false
let last_day_leap = leap_date.month_last_day(); // 2024-02-29
Why it's unique: Direct month boundary detection and last day calculation.
ð§ Data Normalization
Automatic Date Normalization
// Invalid dates are automatically normalized
let invalid_date = Date::new(2020, 49, 32); // Month 49, Day 32
let normalized = invalid_date.normalize(); // 2024-02-01
let invalid_time = Time::new(25, 70, 80); // Hour 25, Minute 70, Second 80
let normalized_time = invalid_time.normalize(); // 02:10:20
let invalid_dt = DateTime::new(invalid_date, invalid_time, 0);
let normalized_dt = invalid_dt.normalize(); // Properly normalized
Why it's unique: Most libraries throw errors for invalid dates. simple-datetime-rs normalizes them intelligently.
ð MS-DOS Legacy Support
MS-DOS Date/Time Conversion
// Convert from MS-DOS 16-bit date format
let date = Date::from_ms_dos_date(0x354b); // 2006-10-11
let time = Time::from_ms_dos_time(0x7d1c); // 15:40:56
// Convert back to MS-DOS format
let ms_dos_date = date.to_ms_dos_date(); // 0x354b
let ms_dos_time = time.to_ms_dos_time(); // 0x7d1c
Why it's unique: No other major date/time library provides MS-DOS format support for legacy system compatibility.
⥠Microsecond Precision
Built-in Microsecond Support
let time = Time::new_with_microseconds(14, 30, 45, 123456);
let microseconds = time.to_microseconds(); // 52545123456
let milliseconds = time.to_milliseconds(); // 52545123
// Automatic normalization with microseconds
let overflow_time = Time::new_with_microseconds(14, 30, 45, 2000000);
let normalized = overflow_time.normalize(); // 14:30:47.000000
Why it's unique: Native microsecond support without external dependencies.
ð Cross-Platform Time Access
Unified Time Access
// Works identically on native and WASM
let now = DateTime::now();
let today = Date::today();
// Cross-platform current time
let current_seconds = DateTime::now();
let current_milliseconds = DateTime::now_milliseconds();
Why it's unique: Seamless cross-platform time access without platform-specific code.
ð Business Logic Helpers
Weekday Detection
let date = Date::new(2023, 6, 15); // Thursday
let is_weekend = date.is_weekend(); // false
let is_weekday = date.is_week_day(); // true
let is_monday = date.is_monday(); // false
let is_thursday = date.is_thursday(); // true
Leap Year Utilities
let date = Date::new(2024, 6, 15);
let is_leap = date.leap_year(); // true
let next_leap = date.next_leap_year(); // 2028
let recent_leap = date.recent_leap_year(); // 2024
Why it's unique: Comprehensive weekday and leap year utilities in one place.
ð Flexible Timezone Handling
Simple Timezone Management
let mut dt = DateTime::new(date, time, 0); // UTC
dt.set_shift(120); // UTC+2 (2 hours ahead)
let gmt_time = dt.to_seconds_from_unix_epoch_gmt();
// Timezone-aware comparison
let utc_dt = DateTime::new(date, time, 0);
let est_dt = DateTime::new(date, time, -300); // UTC-5
assert_eq!(utc_dt, est_dt); // Same moment in time
Why it's unique: Simple timezone offset management without complex timezone databases.
ðĻ Multiple String Formats
Flexible Formatting
let time = Time::new_with_microseconds(14, 30, 45, 123456);
// Various time formats
let full_time = time.to_string(); // "14:30:45.123456"
let short_time = time.to_hh_mm_string(); // "14:30"
let iso_time = time.to_iso_string(); // "14:30:45.123456"
// DateTime formatting
let dt = DateTime::new(date, time, 0);
let iso_dt = dt.to_iso_8061(); // "2023-06-15T14:30:45.123456Z"
let shift_dt = dt.shift_string(); // "Z" or "+02:00"
Why it's unique: Multiple built-in formatting options without external dependencies.
ð Performance-Optimized Operations
Zero-Allocation Operations
// Many operations avoid allocations
let days = date.to_days(); // Direct calculation
let is_leap = date.leap_year(); // Inline computation
let is_weekend = date.is_weekend(); // Simple modulo operation
// Efficient arithmetic
let future_date = date.add_days(30); // Optimized algorithm
let future_month = date.add_months(6); // Smart month handling
Memory-Efficient Bulk Operations
// Creating 1000 dates is extremely memory efficient
let mut dates = Vec::with_capacity(1000);
for i in 0..1000 {
dates.push(Date::new(2023, 6, 15 + (i % 30)));
}
// Only 24KB for 1000 Date objects
ð Validation and Error Handling
Comprehensive Validation
// Built-in validation
let valid_date = Date::new(2023, 6, 15);
let is_valid = valid_date.valid(); // true
let invalid_date = Date::new(2023, 2, 30);
let is_invalid = invalid_date.valid(); // false
// Time validation
let valid_time = Time::new(14, 30, 45);
let is_time_valid = valid_time.valid(); // true
let invalid_time = Time::new(25, 0, 0);
let is_time_invalid = invalid_time.valid(); // false
Use Cases Where simple-datetime-rs Excels
High-Performance Applications
- Data processing pipelines where memory efficiency matters
- Real-time systems requiring predictable performance
- Web applications with high date/time operation volume
- Embedded systems with memory constraints
Bulk Operations
- Batch processing of date/time data
- Time series analysis with many timestamps
- Log processing with frequent date parsing
- Financial applications with high-frequency calculations
Memory-Constrained Environments
- WebAssembly applications where bundle size matters
- Mobile applications with limited memory
- IoT devices with resource constraints
- Microservices requiring minimal memory footprint
Legacy System Integration
- MS-DOS format support for legacy file systems
- Cross-platform compatibility for embedded systems
Business Applications
- Quarter calculations for financial reporting
- Month boundary operations for billing cycles
- Weekday detection for business logic
Data Processing
- Normalization for cleaning invalid data
- Year day calculations for time series analysis
- Microsecond precision for high-frequency data
Performance-Critical Applications
- Zero-allocation operations for real-time systems
- Memory-efficient bulk operations for data processing
- Cross-platform time access for web applications
API Design Philosophy
Simple and Intuitive
// Clean, readable API
let date = Date::new(2023, 6, 15);
let time = Time::new(14, 30, 45);
let datetime = DateTime::new(date, time, 0);
// Natural arithmetic operations
let future_date = date.add_days(30);
let future_time = time + Time::new(1, 0, 0);
Zero-Copy Operations
// Many operations avoid unnecessary allocations
let days = date.to_days(); // Direct calculation
let is_leap = date.leap_year(); // Inline computation
let is_weekend = date.is_weekend(); // Simple modulo operation
Flexible Parsing
// Parse from various formats
let date: Date = "2023-06-15".parse()?;
let time: Time = "14:30:45.123456".parse()?;
let datetime: DateTime = "2023-06-15T14:30:45Z".parse()?;
ð Serde Serialization Support (Optional)
Compact Serialization Formats
Enable serde support with the serde feature for efficient JSON serialization:
[dependencies]
simple-datetime-rs = { version = "0.3.0", features = ["serde"] }
Default Format (Unix Epoch)
By default, types serialize to compact numeric formats:
use serde_json;
// Date: serializes as u64 (seconds since unix epoch at midnight)
let date = Date::new(2024, 1, 15);
let json = serde_json::to_string(&date)?; // "1705276800"
let deserialized: Date = serde_json::from_str(&json)?;
// Time: serializes as u64 (microseconds since midnight, fits in 56 bits)
let time = Time::new(12, 30, 45);
let json = serde_json::to_string(&time)?; // "45045000000"
let deserialized: Time = serde_json::from_str(&json)?;
// DateTime: serializes as u64 (seconds since unix epoch in UTC)
let dt = DateTime::new(date, time, 0);
let json = serde_json::to_string(&dt)?; // "1705321845"
let deserialized: DateTime = serde_json::from_str(&json)?;
// Note: Deserialized DateTime is always in UTC (shift_minutes = 0)
Struct Format (Optional)
For human-readable JSON, use the serde-struct feature:
[dependencies]
simple-datetime-rs = { version = "0.3.0", features = ["serde-struct"] }
// Date: serializes as {"year": 2024, "month": 1, "day": 15}
let date = Date::new(2024, 1, 15);
let json = serde_json::to_string(&date)?;
// {"year":2024,"month":1,"day":15}
// DateTime: serializes with all fields including timezone
let dt = DateTime::new(date, time, -300); // UTC-5
let json = serde_json::to_string(&dt)?;
// {"date":{"year":2024,"month":1,"day":15},"time":{"hour":12,"minute":30,"second":45,"microsecond":0},"shift_minutes":-300}
Why it's unique:
- Compact default format: Efficient numeric serialization for APIs and databases
- Configurable formats: Choose between compact (unix epoch) or readable (struct) formats
- UTC-first design: DateTime serializes as UTC by default, following standard practices
- Time precision: Microseconds preserved in compact 56-bit format
Performance Characteristics
Strengths
- Memory efficiency: 12.9x better than chrono for DateTime operations
- Parsing speed: 17.2x faster date parsing, 12.4x faster time parsing
- Date conversion: 35.7% improvement in from_days() operations
- Days arithmetic: 54.9% improvement in add_days(), 61.5% improvement in sub_days()
- Workflow performance: 1.25x faster end-to-end operations
- Predictable performance: Consistent timing across operations
- Low overhead: Minimal runtime cost for common operations
Trade-offs
- Creation speed: chrono is faster for basic object creation
- Arithmetic operations: chrono has optimized algorithms for some operations
- Feature completeness: chrono has more extensive timezone and formatting support
When to Choose simple-datetime-rs
Choose simple-datetime-rs when:
- Memory efficiency is critical (12.9x better)
- Parsing performance matters (17.2x faster date parsing, 12.4x faster time parsing)
- Date conversion operations are frequent (35.7% improvement)
- Days arithmetic is common (54.9% faster add_days, 61.5% faster sub_days)
- Bulk operations are common
- WASM compatibility is required
- Zero dependencies are preferred (pure Rust, no unsafe code)
- Predictable performance is needed
- Memory safety is paramount (100% safe Rust)
Choose chrono when:
- Extensive timezone support is required
- Complex formatting is needed
- Maximum creation speed is critical
- Rich ecosystem integration is important
Benchmarking
The library includes comprehensive benchmarks comparing performance against chrono and std::time:
# Run performance comparisons
cargo bench --bench performance_comparison
# Generate HTML reports
cargo bench --bench performance_comparison -- --html
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Performance Summary
simple-datetime-rs provides a compelling alternative to chrono for applications where:
- Memory efficiency is paramount (12.9x better for DateTime operations)
- String parsing performance matters (17.2x faster date parsing, 12.4x faster time parsing)
- Date conversion operations are frequent (35.7% improvement)
- Days arithmetic is common (54.9% faster add_days, 61.5% faster sub_days)
- End-to-end workflows need optimization (1.25x faster complete operations)
- Minimal dependencies are preferred
- WASM compatibility is required
While chrono excels in creation speed and feature completeness, simple-datetime-rs offers dramatic advantages in parsing performance, days arithmetic, and memory usage, making it an excellent choice for high-performance applications and memory-constrained environments.
Feature Summary
simple-datetime-rs provides unique functionality that combines:
- Legacy compatibility (MS-DOS support)
- Business logic helpers (quarters, weekdays, leap years)
- Data normalization (intelligent invalid date handling)
- High precision (microsecond support)
- Cross-platform (native and WASM)
- Performance optimization (zero-allocation, memory-efficient)
- Serde support (optional compact or readable JSON serialization)
These features make simple-datetime-rs particularly well-suited for:
- Legacy system integration
- Business applications
- Data processing pipelines
- Performance-critical applications
- Cross-platform development
Dependencies
~0â255KB