├── .gitignore ├── .github └── dependabot.yml ├── Cargo.toml ├── LICENSE ├── example └── main.rs ├── README.md └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "21:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "aion" 3 | version = "0.2.0" 4 | authors = ["Gan Jun Kai "] 5 | edition = "2018" 6 | description = "A friendly Rust duration and datetime utility crate" 7 | repository = "https://github.com/jk-gan/aion" 8 | license = "MIT" 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | chrono = "0.4" 14 | 15 | [[example]] 16 | name = "example" 17 | path = "example/main.rs" 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Gan Jun Kai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/main.rs: -------------------------------------------------------------------------------- 1 | use aion::*; 2 | use chrono::{TimeZone, Utc}; 3 | 4 | fn main() { 5 | // Easily represent a chrono::Duration 6 | let two_days = 2.days(); 7 | println!("2 days: {:?}", two_days); 8 | let attention_span = 1.seconds(); 9 | println!("Attention span: {:?}", attention_span); 10 | 11 | // Add or subtract durations from the current time (UTC) 12 | let now = Utc::now(); 13 | let three_hours_from_now = now + 3.hours(); 14 | println!("3 hours from now: {}", three_hours_from_now); 15 | let two_hours_from_now = 2.hours().from_now(); 16 | println!("2 hours from now: {}", two_hours_from_now); 17 | let last_week = 7.days().ago(); // or 1.weeks().ago() 18 | println!("1 week ago: {}", last_week); 19 | 20 | // More complex DateTimes can be represented using before() and after() methods 21 | let christmas = Utc.ymd(2020, 12, 25).and_hms(0, 0, 0); 22 | let two_weeks_before_christmas = 2.weeks().before(christmas); 23 | println!("2 weeks before christmas: {}", two_weeks_before_christmas); 24 | let boxing_day = 1.days().after(christmas); 25 | println!("Boxing day: {}", boxing_day); 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Aion [![](https://img.shields.io/crates/v/aion.svg)](https://crates.io/crates/aion) 2 | Aion is a utility crate, inspired by rails, that allows you to write `Duration` and `DateTime` in a friendly way: 3 | ```rust 4 | // Easily represent a chrono::Duration 5 | let two_days = 2.days(); 6 | let attention_span = 1.seconds(); 7 | 8 | // Add or subtract durations from the current time (UTC) 9 | let now = Utc::now(); 10 | let three_hours_from_now = now + 3.hours(); 11 | let two_hours_from_now = 2.hours().from_now(); 12 | let last_week = 7.days().ago(); // or 1.weeks().ago() 13 | 14 | // More complex DateTimes can be represented using before() and after() methods 15 | let christmas = Utc.ymd(2020, 12, 25).and_hms(0, 0, 0); 16 | let two_weeks_before_christmas = 2.weeks().before(christmas); 17 | let boxing_day = 1.days().after(christmas); 18 | ``` 19 | 20 | ## Installation 21 | Add this to your `Cargo.toml` file: 22 | ```toml 23 | [dependencies] 24 | aion = "0.2" 25 | ``` 26 | 27 | ## Example 28 | The example is located in `example` folder. You can run it by using 29 | ```bash 30 | cargo run --example example 31 | ``` 32 | 33 | ## Limitations 34 | Currently this crate only will return `DateTime`. 35 | 36 | ## Acknowledgement 37 | This crate is using [chrono](https://github.com/chronotope/chrono). Thanks for this awesome crate. 38 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use chrono::{DateTime, Duration, Utc}; 2 | 3 | pub trait DurationExtension { 4 | fn weeks(self) -> Duration; 5 | fn days(self) -> Duration; 6 | fn hours(self) -> Duration; 7 | fn minutes(self) -> Duration; 8 | fn seconds(self) -> Duration; 9 | fn milliseconds(self) -> Duration; 10 | fn microseconds(self) -> Duration; 11 | fn nanoseconds(self) -> Duration; 12 | } 13 | 14 | pub trait DateTimeExtension { 15 | fn before(self, other: DateTime) -> DateTime; 16 | fn after(self, other: DateTime) -> DateTime; 17 | 18 | fn ago(self) -> DateTime 19 | where 20 | Self: DateTimeExtension + Sized, 21 | { 22 | self.before(Utc::now()) 23 | } 24 | 25 | fn from_now(self) -> DateTime 26 | where 27 | Self: DateTimeExtension + Sized, 28 | { 29 | self.after(Utc::now()) 30 | } 31 | } 32 | 33 | macro_rules! duration_extension { 34 | ($($type:ident), +) => { 35 | impl DurationExtension for i64 { 36 | $( 37 | fn $type(self) -> Duration { 38 | Duration::$type(self) 39 | } 40 | )* 41 | } 42 | }; 43 | } 44 | duration_extension!( 45 | weeks, 46 | days, 47 | hours, 48 | minutes, 49 | seconds, 50 | milliseconds, 51 | microseconds, 52 | nanoseconds 53 | ); 54 | 55 | impl DateTimeExtension for Duration { 56 | fn before(self, other: DateTime) -> DateTime { 57 | other - self 58 | } 59 | 60 | fn after(self, other: DateTime) -> DateTime { 61 | other + self 62 | } 63 | } 64 | 65 | #[cfg(test)] 66 | mod tests { 67 | use super::*; 68 | use chrono::{Duration, Utc}; 69 | 70 | #[test] 71 | fn duration() { 72 | assert_eq!(2.weeks(), Duration::weeks(2)); 73 | assert_eq!(2.days(), Duration::days(2)); 74 | assert_eq!(2.hours(), Duration::hours(2)); 75 | assert_eq!(2.minutes(), Duration::minutes(2)); 76 | assert_eq!(2.seconds(), Duration::seconds(2)); 77 | assert_eq!(2.milliseconds(), Duration::milliseconds(2)); 78 | assert_eq!(2.microseconds(), Duration::microseconds(2)); 79 | assert_eq!(2.nanoseconds(), Duration::nanoseconds(2)); 80 | } 81 | 82 | #[test] 83 | fn days_before() { 84 | let now = Utc::now(); 85 | assert_eq!(2.days().before(now), now - Duration::days(2)); 86 | } 87 | 88 | #[test] 89 | fn days_after() { 90 | let now = Utc::now(); 91 | assert_eq!(2.days().after(now), now + Duration::days(2)); 92 | } 93 | } 94 | --------------------------------------------------------------------------------