range_date
A powerful Rust crate for handling date periods with embedded data and comprehensive date range operations.
Features
- ๐๏ธ Rich Date Periods: Enum-based periods with embedded year/index data - Year(u32), Quarter(u32, u32), Month(u32, u32), Daily(u32, u32)
- ๐ Type Conversion: String parsing and serialization support with validation
- ๐ Date Range Operations: Calculate first/last days, check date containment
- ๐ฏ Date Conversion: Convert NaiveDate to any period type
- ๐ Advanced Period Operations: Navigate between periods (succ/pred), decompose into sub-periods, aggregate to parent periods
- ๐ Range Generation: Generate all periods between two dates for comprehensive date range analysis
- ๐ Comprehensive Documentation: 26+ doc tests with practical examples for all public methods
- โก High Performance: Built on top of the efficient
chronolibrary - ๐ก๏ธ Type Safety: Complete validation with proper error handling
- ๐งช Leap Year Support: Accurate leap year detection and day validation
Quick Start
Add this to your Cargo.toml:
[]
= "0.2.1"
Usage Examples
Basic Usage
use DatePeriod;
use FromStr;
// Create date periods with validation
let q1_2024 = quarter.unwrap;
let may_2024 = month.unwrap;
// String representation
println!; // Output: 2024Q1
println!; // Output: 2024M5
// Parse from string
let parsed = from_str.unwrap;
println!; // DatePeriod::Month(2024, 3)
// Get date ranges
let first_day = q1_2024.get_first_day?; // 2024-01-01
let last_day = q1_2024.get_last_day?; // 2024-03-31
Date Period Construction
use DatePeriod;
// Create with validation
let year_2024 = year;
let q2_2024 = quarter.unwrap; // Q2: April-June
let march_2024 = month.unwrap; // March
let day_60 = daily.unwrap; // 60th day of 2024
// Validation catches errors
assert!; // Quarter 5 doesn't exist
assert!; // Month 13 doesn't exist
assert!; // Day 366 invalid in non-leap year
Date Conversion
use DatePeriod;
use NaiveDate;
let date = from_ymd_opt.unwrap; // August 15, 2024
// Convert to different period types
let as_year = from_date_as_year; // 2024Y
let as_quarter = from_date_as_quarter; // 2024Q3
let as_month = from_date_as_month; // 2024M8
let as_daily = from_date_as_daily; // 2024D228
Date Range Operations
use DatePeriod;
use NaiveDate;
let q1_2024 = quarter.unwrap;
// Get date boundaries
let start = q1_2024.get_first_day?; // 2024-01-01
let end = q1_2024.get_last_day?; // 2024-03-31
// Check date containment
let valentine = from_ymd_opt.unwrap;
let contains = q1_2024.contains_date; // true
Serialization Support
use DatePeriod;
use serde_json;
let quarter = quarter.unwrap;
let json = to_string.unwrap;
println!; // "2024Q2"
let deserialized: DatePeriod = from_str.unwrap;
assert_eq!;
Advanced Period Operations [NEW]
use DatePeriod;
use NaiveDate;
// Range generation - Generate all periods between two dates
let start = from_ymd_opt.unwrap;
let end = from_ymd_opt.unwrap;
let quarters = between_date_as_quarter.unwrap;
assert_eq!; // Q1 and Q2 2024
// Period navigation - Get next/previous periods
let q1 = quarter.unwrap;
let q2 = q1.succ.unwrap; // Next: 2024Q2
let back_to_q1 = q2.pred.unwrap; // Previous: 2024Q1
// Period decomposition - Break down into sub-periods
let year_2024 = year;
let quarters_in_year = year_2024.decompose;
assert_eq!; // 4 quarters in a year
// Period aggregation - Get parent period
let month = month.unwrap;
let quarter = month.aggregate;
assert_eq!;
Period Information Queries [NEW]
use DatePeriod;
let period = quarter.unwrap;
// Query period information
assert_eq!;
assert_eq!; // Quarter number
assert_eq!;
assert_eq!;
Date Range Format
The crate uses a compact string format for date periods:
- Format:
YYYY[PERIOD][INDEX] - Examples:
2024Y- Year 20242024Q2- Q2 2024 (April-June)2024M03- March 20242024D060/2024D60- 60th day of 2024
Period Types
| Period | Constructor | String Format | Description |
|---|---|---|---|
| Year | DatePeriod::year(2024) |
2024Y |
Entire year |
| Quarter | DatePeriod::quarter(2024, 1) |
2024Q1 |
Q1: Jan-Mar, Q2: Apr-Jun, etc. |
| Month | DatePeriod::month(2024, 3) |
2024M3 |
Specific month (1-12) |
| Daily | DatePeriod::daily(2024, 60) |
2024D60 |
Specific day of year (1-366) |
API Documentation
For complete API documentation, visit docs.rs.
Testing
Run the comprehensive test suite:
# Run all tests
# Run specific test files
# Run tests with output for manual verification
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
We welcome contributions! Here are several ways you can help:
๐ Found a Bug?
- Open an issue with a clear description
- Include code examples that reproduce the problem
- Mention your Rust version and operating system
๐ก Have a Feature Request?
- Check existing issues to avoid duplicates
- Open a new issue describing your use case and proposed solution
- Explain why this feature would be valuable
๐ง Want to Contribute Code?
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with comprehensive tests
- Ensure all tests pass (
cargo test) - Run formatting (
cargo fmt) and linting (cargo clippy) - Commit your changes (
git commit -am 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ Documentation Improvements?
- Documentation improvements are always welcome
- Update examples in README.md or code comments
- Help improve API documentation
Have questions or suggestions? Please open an issue - we'd love to hear from you!