Giter Site home page Giter Site logo

chrono's People

Contributors

botahamec avatar conradludgate avatar danwilliams avatar dekellum avatar dependabot[bot] avatar did92 avatar djc avatar emschwartz avatar esheppa avatar evq avatar greyblake avatar harkonenbade avatar ijanos avatar jtmoon79 avatar kevinmatthes avatar kijewski avatar kodraus avatar kroisse avatar lifthrasiir avatar lingman avatar michalsrb avatar milo123459 avatar mkroening avatar mqudsi avatar nickelc avatar pitdicker avatar quodlibetor avatar robyoung avatar shadoysv avatar yu-re-ka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chrono's Issues

Owned DelayedFormat struct

Hi!

Sometimes it's required to precompile some strftime pattern known at runtime to be repeatedly consumed in the future in conjunction with timestamp to produce formatted strings.

I see there is DelayedFormat, but it requires lifetime specifier in its Iterator type which makes it (seems like) impossible or quite tricky to save somewhere for further usage.

It would be great if you think about some kind of owned DelayedFormat struct or point me how to adapt current struct for this case.

Leap year and last day of month

Would you mind adding something like:

fn is_leap_year(year: i32) -> bool {
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
}

fn last_day_of_month(year: i32, month: u32) -> u32 {
    match month {
        1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
        4 | 6 | 9 | 11 => 30,
        2 => if is_leap_year(year) { 29 } else { 28 },
        _ => panic!("invalid month: {}" , month),
    }
}

?
Thanks.

Hash implementations

It'd be nice to offer Hash implementations for all of the date/time structs so that they can be used as keys in HashMaps.

Format Datetime Using Iterator <Item>

Is it possible to use an iterator of Item to format a DateTime, like we can do for parsing to Parsed?

If not, I don't think it'd be too hard for me to do myself.

Initialization macros

date!(2014-11-30), time!(12:34), datetime!(2014-11-30 12:34)? The current initialization syntax is somewhat verbose. It can be theoretically done without a procedural macro, provided that we keep away from the strict syntax of ISO 8601 (no datetime!(2014-11-30T12:34) etc.).

Fails to build with time v0.1.3

rust-chrono seems to fail building. I'm not sure if this is because of an update in the time library, or an update in rust nightly, or both. It is using time v0.1.3 instead of v0.1.2 though.

Here's the compiler output:

$ cargo build -v
       Fresh gcc v0.1.1 (https://github.com/alexcrichton/gcc-rs#d35c34c8)
       Fresh time v0.1.3 (https://github.com/rust-lang/time#914a4840)
   Compiling chrono v0.1.4 (file:///home/daboross/Projects/CheckedOut/rust-chrono)
     Running `rustc /home/daboross/Projects/CheckedOut/rust-chrono/src/lib.rs --crate-name chrono --crate-type lib -g -C metadata=0738b31a438449f6 -C extra-filename=-0738b31a438449f6 --out-dir /home/daboross/Projects/CheckedOut/rust-chrono/target --dep-info /home/daboross/Projects/CheckedOut/rust-chrono/target/.fingerprint/chrono-0738b31a438449f6/dep-lib-chrono -L /home/daboross/Projects/CheckedOut/rust-chrono/target -L /home/daboross/Projects/CheckedOut/rust-chrono/target/deps --extern time=/home/daboross/Projects/CheckedOut/rust-chrono/target/deps/libtime-1d6301158a291dc6.rlib -L /home/daboross/Projects/CheckedOut/rust-chrono/target/build/time-1d6301158a291dc6/out`
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:381:5: 395:6 error: method `add` has an incompatible type for trait: expected struct naive::date::NaiveDate, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:381     fn add(&self, rhs: &Duration) -> NaiveDate {
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:382         // TODO overflow currently fails
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:383 
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:384         let year = self.year();
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:385         let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:386         let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
                                                                     ...
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:400:5: 400:66 error: method `add` has an incompatible type for trait: expected struct std::time::duration::Duration, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:400     fn add(&self, rhs: &NaiveDate) -> NaiveDate { rhs.add(self) }
                                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:400:59: 400:63 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:400     fn add(&self, rhs: &NaiveDate) -> NaiveDate { rhs.add(self) }
                                                                                                                               ^~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:404:5: 412:6 error: method `sub` has an incompatible type for trait: expected struct naive::date::NaiveDate, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:404     fn sub(&self, rhs: &NaiveDate) -> Duration {
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:405         let year1 = self.year();
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:406         let year2 = rhs.year();
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:407         let (year1_div_400, year1_mod_400) = div_mod_floor(year1, 400);
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:408         let (year2_div_400, year2_mod_400) = div_mod_floor(year2, 400);
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:409         let cycle1 = internals::yo_to_cycle(year1_mod_400 as u32, self.of().ordinal()) as i64;
                                                                     ...
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:417:5: 417:68 error: method `sub` has an incompatible type for trait: expected struct naive::date::NaiveDate, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:417     fn sub(&self, rhs: &Duration) -> NaiveDate { self.add(&-*rhs) }
                                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:417:59: 417:65 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/date.rs:417     fn sub(&self, rhs: &Duration) -> NaiveDate { self.add(&-*rhs) }
                                                                                                                               ^~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:175:5: 190:6 error: method `add` has an incompatible type for trait: expected struct naive::time::NaiveTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:175     fn add(&self, rhs: &Duration) -> NaiveTime {
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:176         // there is no direct interface in `Duration` to get only the nanosecond part,
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:177         // so we need to do the additional calculation here.
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:178         let rhs2 = *rhs - Duration::seconds(rhs.num_seconds());
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:179         let mut secs = self.secs + (rhs.num_seconds() % 86400 + 86400) as u32;
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:180         let mut nanos = self.frac + rhs2.num_nanoseconds().unwrap() as u32;
                                                                     ...
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:195:5: 195:66 error: method `add` has an incompatible type for trait: expected struct std::time::duration::Duration, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:195     fn add(&self, rhs: &NaiveTime) -> NaiveTime { rhs.add(self) }
                                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:195:59: 195:63 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:195     fn add(&self, rhs: &NaiveTime) -> NaiveTime { rhs.add(self) }
                                                                                                                               ^~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:199:5: 212:6 error: method `sub` has an incompatible type for trait: expected struct naive::time::NaiveTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:199     fn sub(&self, rhs: &NaiveTime) -> Duration {
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:200         // the number of whole non-leap seconds
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:201         let secs = self.secs as i64 - rhs.secs as i64 - 1;
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:202 
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:203         // the fractional second from the rhs to the next non-leap second
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:204         let maxnanos = if rhs.frac >= 1_000_000_000 {2_000_000_000} else {1_000_000_000};
                                                                     ...
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:217:5: 217:68 error: method `sub` has an incompatible type for trait: expected struct naive::time::NaiveTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:217     fn sub(&self, rhs: &Duration) -> NaiveTime { self.add(&-*rhs) }
                                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:217:59: 217:65 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/time.rs:217     fn sub(&self, rhs: &Duration) -> NaiveTime { self.add(&-*rhs) }
                                                                                                                               ^~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:166:5: 183:6 error: method `add` has an incompatible type for trait: expected struct naive::datetime::NaiveDateTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:166     fn add(&self, rhs: &Duration) -> NaiveDateTime {
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:167         // Duration does not directly give its parts, so we need some additional calculations.
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:168         let days = rhs.num_days();
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:169         let nanos = (*rhs - Duration::days(days)).num_nanoseconds().unwrap();
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:170         debug_assert!(Duration::days(days) + Duration::nanoseconds(nanos) == *rhs);
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:171         debug_assert!(-86400_000_000_000 < nanos && nanos < 86400_000_000_000);
                                                                         ...
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:188:5: 188:74 error: method `add` has an incompatible type for trait: expected struct std::time::duration::Duration, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:188     fn add(&self, rhs: &NaiveDateTime) -> NaiveDateTime { rhs.add(self) }
                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:188:67: 188:71 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:188     fn add(&self, rhs: &NaiveDateTime) -> NaiveDateTime { rhs.add(self) }
                                                                                                                                           ^~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:192:5: 194:6 error: method `sub` has an incompatible type for trait: expected struct naive::datetime::NaiveDateTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:192     fn sub(&self, rhs: &NaiveDateTime) -> Duration {
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:193         (self.date - rhs.date) + (self.time - rhs.time)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:194     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:199:5: 199:72 error: method `sub` has an incompatible type for trait: expected struct naive::datetime::NaiveDateTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:199     fn sub(&self, rhs: &Duration) -> NaiveDateTime { self.add(&-*rhs) }
                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:199:63: 199:69 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/naive/datetime.rs:199     fn sub(&self, rhs: &Duration) -> NaiveDateTime { self.add(&-*rhs) }
                                                                                                                                       ^~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:265:5: 267:6 error: method `add` has an incompatible type for trait: expected struct date::Date, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:265     fn add(&self, rhs: &Duration) -> Date<Off> {
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:266         Date { date: self.date + *rhs, offset: self.offset.clone() }
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:267     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:272:5: 272:66 error: method `add` has an incompatible type for trait: expected struct std::time::duration::Duration, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:272     fn add(&self, rhs: &Date<Off>) -> Date<Off> { rhs.add(self) }
                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:272:59: 272:63 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:272     fn add(&self, rhs: &Date<Off>) -> Date<Off> { rhs.add(self) }
                                                                                                                         ^~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:276:5: 278:6 error: method `sub` has an incompatible type for trait: expected struct date::Date, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:276     fn sub(&self, rhs: &Date<Off2>) -> Duration {
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:277         self.date - rhs.date
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:278     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:283:5: 283:68 error: method `sub` has an incompatible type for trait: expected struct date::Date, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:283     fn sub(&self, rhs: &Duration) -> Date<Off> { self.add(&-*rhs) }
                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:283:59: 283:65 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/date.rs:283     fn sub(&self, rhs: &Duration) -> Date<Off> { self.add(&-*rhs) }
                                                                                                                         ^~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:114:5: 116:6 error: method `add` has an incompatible type for trait: expected struct time::Time, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:114     fn add(&self, rhs: &Duration) -> Time<Off> {
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:115         Time { time: self.time + *rhs, offset: self.offset.clone() }
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:116     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:121:5: 121:66 error: method `add` has an incompatible type for trait: expected struct std::time::duration::Duration, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:121     fn add(&self, rhs: &Time<Off>) -> Time<Off> { rhs.add(self) }
                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:121:59: 121:63 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:121     fn add(&self, rhs: &Time<Off>) -> Time<Off> { rhs.add(self) }
                                                                                                                         ^~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:125:5: 127:6 error: method `sub` has an incompatible type for trait: expected struct time::Time, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:125     fn sub(&self, rhs: &Time<Off2>) -> Duration {
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:126         self.time - rhs.time
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:127     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:132:5: 132:68 error: method `sub` has an incompatible type for trait: expected struct time::Time, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:132     fn sub(&self, rhs: &Duration) -> Time<Off> { self.add(&-*rhs) }
                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:132:59: 132:65 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/time.rs:132     fn sub(&self, rhs: &Duration) -> Time<Off> { self.add(&-*rhs) }
                                                                                                                         ^~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:186:5: 188:6 error: method `add` has an incompatible type for trait: expected struct datetime::DateTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:186     fn add(&self, rhs: &Duration) -> DateTime<Off> {
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:187         DateTime { datetime: self.datetime + *rhs, offset: self.offset.clone() }
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:188     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:193:5: 193:74 error: method `add` has an incompatible type for trait: expected struct std::time::duration::Duration, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:193     fn add(&self, rhs: &DateTime<Off>) -> DateTime<Off> { rhs.add(self) }
                                                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:193:67: 193:71 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:193     fn add(&self, rhs: &DateTime<Off>) -> DateTime<Off> { rhs.add(self) }
                                                                                                                                     ^~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:197:5: 199:6 error: method `sub` has an incompatible type for trait: expected struct datetime::DateTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:197     fn sub(&self, rhs: &DateTime<Off2>) -> Duration {
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:198         self.datetime - rhs.datetime
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:199     }
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:204:5: 204:72 error: method `sub` has an incompatible type for trait: expected struct datetime::DateTime, found &-ptr [E0053]
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:204     fn sub(&self, rhs: &Duration) -> DateTime<Off> { self.add(&-*rhs) }
                                                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:204:63: 204:69 error: mismatched types: expected `std::time::duration::Duration`, found `&std::time::duration::Duration` (expected struct std::time::duration::Duration, found &-ptr)
/home/daboross/Projects/CheckedOut/rust-chrono/src/datetime.rs:204     fn sub(&self, rhs: &Duration) -> DateTime<Off> { self.add(&-*rhs) }
                                                                                                                                 ^~~~~~
error: aborting due to 36 previous errors
Could not compile `chrono`.

Caused by:
  Process didn't exit successfully: `rustc /home/daboross/Projects/CheckedOut/rust-chrono/src/lib.rs --crate-name chrono --crate-type lib -g -C metadata=0738b31a438449f6 -C extra-filename=-0738b31a438449f6 --out-dir /home/daboross/Projects/CheckedOut/rust-chrono/target --dep-info /home/daboross/Projects/CheckedOut/rust-chrono/target/.fingerprint/chrono-0738b31a438449f6/dep-lib-chrono -L /home/daboross/Projects/CheckedOut/rust-chrono/target -L /home/daboross/Projects/CheckedOut/rust-chrono/target/deps --extern time=/home/daboross/Projects/CheckedOut/rust-chrono/target/deps/libtime-1d6301158a291dc6.rlib -L /home/daboross/Projects/CheckedOut/rust-chrono/target/build/time-1d6301158a291dc6/out` (status=101)

Timezone offset colon formatting

The documentation for both strftime %z and the TimezoneOffset item indicates that a colon should be printed between the hour and minute values of the timezone offset. This is not the case - which behaviour is intended, is it the code or the documentation that's incorrect?

Confusing (documentation of) formatting of fractional seconds

I'm quite confused about the formatting of fractional seconds. The documentation seems to be inconsistent and there are some places in the code that I think are bugs (just from looking at the code, not actually encountered them).

I'm using log4rs for logging in my application and there was this strange effect with fractional seconds:
Im using the {d} formatter in, which according to the documentation uses the ISO 6801 format.

Now, almost all entries have a precision of exactly 9 digits, but every now and then (maybe after about 50 entries), there is an entry with 6 digits.

Example:

2016-04-19T21:44:43.983416760+00:00 ...
2016-04-19T21:44:49.199616120+00:00 ...
2016-04-19T21:45:30.639604840+00:00 ...
2016-04-19T21:45:30.641324440+00:00 ...
2016-04-19T21:45:43.573686080+00:00 ...
2016-04-19T23:47:39.533879920+00:00 ...
2016-04-20T01:48:21.214988880+00:00 ...
2016-04-20T03:49:14.854611400+00:00 ...
2016-04-20T05:50:07.723535600+00:00 ...
2016-04-20T07:50:59.404401+00:00 ...
2016-04-20T08:55:44.798731960+00:00 ...
2016-04-20T08:55:44.799131760+00:00 ...
2016-04-20T08:57:44.209481360+00:00 ...
2016-04-20T08:57:44.266084640+00:00 ...
2016-04-20T08:57:44.293876080+00:00 ...
2016-04-20T09:51:53.068258480+00:00 ...
2016-04-20T11:52:43.275364520+00:00 ...
2016-04-20T13:53:36.395558920+00:00 ...
2016-04-20T15:54:27.967924880+00:00 ...
2016-04-20T17:55:19.631437880+00:00 ...
2016-04-20T18:17:03.745529880+00:00 ...
2016-04-20T18:30:06.031285560+00:00 ...

First I was confused about this, thought that it was a bug, then I read the documentation and see that it's probably by design.
But I really don't see the advantage of this. It cannot be used as fixed width, but it's also not really variable width. It combines the disadvantages of both IMO.

Then, digging through the code, I found this comment in format/mod.rs:423

                    RFC3339 => // (almost) same to `%Y-%m-%dT%H:%M:%S.%f%z`

buf documentation says:

6. `%+`:
   This one is close to, but not identical to, `%Y-%m-%dT%H:%M:%S%.f%z`.

and according to the documentation, the %f specifier is fixed precision of 9, only %.f uses steps of 3/6/9.
Now, which one is correct?

There's also an typo in the documentation (strftime.rs:134):

   The variant `%.3f`, `%.3f` and `%.3f` are left-aligned and print 3, 6 or 9 fractional digits

And I'm really not sure if the nano == 0 cases here are copy/paste bugs:

                    Nanosecond3 =>
                        time.map(|t| {
                            let nano = t.nanosecond() % 1_000_000_000;
                            if nano == 0 {
                                write!(w, ".000")
                            } else {
                                write!(w, ".{:03}", nano / 1_000_000)
                            }
                        }),
                    Nanosecond6 =>
                        time.map(|t| {
                            let nano = t.nanosecond() % 1_000_000_000;
                            if nano == 0 {
                                write!(w, ".000")
                            } else {
                                write!(w, ".{:06}", nano / 1_000)
                            }
                        }),
                    Nanosecond9 =>
                        time.map(|t| {
                            let nano = t.nanosecond() % 1_000_000_000;
                            if nano == 0 {
                                write!(w, ".000")
                            } else {
                                write!(w, ".{:09}", nano)
                            }
                        }),

I don't even understand, why this case is handled separately, so I'm possibly misunderstanding something...

Serde Support?

It seems like chrono has serde support but I'm getting

error: the trait bound `chrono::DateTime<chrono::UTC>: event::serde::Deserialize` is not satisfied`

When trying to use it. I'm relatively new to Rust, am I missing something?

Thanks in advance.

edit: I'm on stable

Additional formatting syntax

The current format method is directly based on strftime. While this is not that bad, it historically has been a source of confusion which lead to many bugs, e.g. Twitter's ISO weekdate bug.

Some syntaxes to consider:

  • Go's "format-by-example" syntax (http://golang.org/pkg/time/#pkg-constants). Cons: It doesn't fully cover the use case of strftime. Possibly we can go with an additional method named format_like.
  • std::fmt-inspired syntax. {YYYY}-{MM}-{DD} {hh}:{mm}:{ss.sss} {+xx:xx}? Not sure about the specifier.

Implement fmt::String for offset::Local?

When trying to use format() on chrono::Local::now(), I'm getting the following error:

error: type `chrono::datetime::DateTime<chrono::offset::Local>` does not implement any method in scope named `format`

Local::now().to_string() also fails with:

error: type `chrono::datetime::DateTime<chrono::offset::Local>` does not implement any method in scope named `to_string`

I believe this is due to chrono::offset::Local not implementing std::fmt::String, where the other offsets do.

Local.ymd gives wrong day

Hey,

I used something like

let d = Local.ymd(2999, 12, 28).and_hms(23, 59, 59)

in my code. However

d.day()

gives 27.

UPDATE: Interesting, works in Travis CI but not with my local version

Generated `RustcDecodable` impl is not very safe

Since Chrono does not contain an unsafe code this is not a much threat, but it can destroy internal consistency in subtle ways (e.g. February 29 in the non-leap year). We may want to add a verification procedure to the RustcDecodable impl, or at least a method to do that posthumously.

NaiveDateTime Duration math seems slightly incorrect

#[test]
fn test() {
    let base = chrono::NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
    let t = -946684799990000;
    let time = base + chrono::Duration::microseconds(t);
    assert_eq!(t, (time - base).num_microseconds().unwrap());
}
thread 'types::chrono::test' panicked at 'assertion failed: `(left == right)` (left: `-946684799990000`, right: `-946684796695032`)', tests/types/chrono.rs:23

Interestingly, this version does pass:

#[test]
fn test() {
    let base = chrono::NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
    let t = -946684799990000;
    let time = base - chrono::Duration::microseconds(t);
    assert_eq!(t, (base - time).num_microseconds().unwrap());
}

UTC Offset is not Send (cannot send DateTime across mps::channel)

I have a struct with a DateTime<UTC> field that I would like to send across a channel, like this:

pub struct Signal {
  pub time: DateTime<UTC>,
  pub raw: String
}

But when I want to create the channel, rustc complains that

error: the trait `core::marker::Send` is not implemented for the type `<chrono::offset::utc::UTC as chrono::offset::TimeZone>::Offset` [    E0277]    

let (new_signal_sender, new_signal_rcvr) = channel::<Signal>();
                                           ^~~~~~~~~~~~~~~~~
note: `<chrono::offset::utc::UTC as chrono::offset::TimeZone>::Offset` cannot be sent between threads safely
let (new_signal_sender, new_signal_rcvr) = channel::<Signal>();

Now Send is easily the part of Rust I understand the least, but I would have expected a DateTime object to be "sendable".

Add an interval type, or modify Duration to allow larger spans

It would be great to have a data type which behaves similarly to the PostgreSQL interval data type. Unlike the duration type currently in Rust Chrono, it stores days and months as separate fields. Days cannot be accurately represented in seconds without a reference instant due to the existence of leap seconds, and months cannot be represented in days or weeks for obvious reasons. It would be great to have a standard target for this type of data type.

Convert Date/Time<T> to Date/Time<U>

rust-chrono has several methods which convert NaiveDate/Time to Date/Time<Off>, but there's no method which do Date/Time<T> to Date/Time<U>, where T and U are different Offsets.

There are two ways of converting the offset of the date/time object:

  • Preserve all of other fields, and replace only the offset info. This behavior likes Python's datetime.replace(tzinfo=new_tz). The duration between the result and the original will be same as a distance of their offsets.
  • Preserve the time, and adjust the date and time data. This behavior likes Python's datetime.astimezone(new_tz). They should have same UTC timestamp that the result and the original.

Local::today() is not today.

I'm using chrono 0.2.18.

If I run the following test program:

extern crate chrono;
use chrono::*;

fn main() {
    let now = Local::now();
    let today = Local::today();
    println!("{:?}", now);
    println!("{:?}", today);
    println!("{:04}-{:02}-{:02}", now.year(), now.month(), now.day());
    println!("{:04}-{:02}-{:02}", today.year(), today.month(), today.day());
}

Here's the output I get:

2016-02-03T16:27:29.757997151-08:00
2016-02-04-08:00
2016-02-03
2016-02-04

Local::now() gives me the right results, but today.day() looks like it forgot to apply the timezone offset (i.e. it's the same as UTC::today().day()).

`DelayedFormat` error handling is not as optimal

Currently an invalid formatting string gives Item::Error in the iterator, and it invokes std::fmt::Error on the actual formatting. I initially assumed that, while this does not immediately fail, a vast majority of .format() call will be followed by .to_string() or formatting macros, and they will fail loudly so the user can be easily notified during the initial test.

Actually, my assumption turned out to be wrong: std::fmt::Error is rarely used (std has no use of it AFAIK) and the failure mode for it is not well-tested nor well-explored. For the striking example, ToString::to_string will abruptly stop at the first such error and happily return the string built up to that point. This is very surprising, and I'm yet to find the rationale for this (rust-lang/rfcs#380 and rust-lang/rfcs#504 should be relevant but they are almost silent on this). The root commit causing this traces back to 2014 and I doubt this is a consistent decision.

Given this "relevation", I plan to change the error handling of DelayedFormat. On the initial construction, it will run a copy of the item iterator and panic on Item::Error (actually, StrftimeItems may have a method for checking this). DelayedFormat already requires the iterator to be Cloneable so this won't cause a direct API change, but this will cause a rescanning of the format string. I guess that is not a big deal, but if it is a big deal we may have a unsafe DelayedFormat constructor. The plan is to make this change to 0.3.

Couldn't get the offset info from the DateTime<Off> value

DateTime<Off> has no way to get its offset information, neither by the method nor by the public field. Even though I knew the exact type Off via the generic parameter or the given type, it's insufficient to know the actual information about the timezone, e.g. offset minutes from UTC in FixedOffset.

Provide `days_in_month()`

For some calculations it's useful to get the number of days in the current month.

For example, I want to get the first and last day in a given month in my current project. The former is possible via .with_day(1), but the latter isn't easily possible (or at least I don't see it)

`Offset` redesign

The current Offset is problematic because we conflate the offset state and offset conversion. Consequently we cannot convert to Local (!). This is because Local is stored alongside the NaiveDateTime and should contain a cached FixedOffset (otherwise every method would slow down).

We cannot simply strip the offset state down, or replace it with the mandatory FixedOffset. Okay, no-overhead DateTime<UTC> might be an illusion, but some Offset implementation would want something other than FixedOffset: Tzfile (#10), for example, would want to store the offset to the most recent transition instead.

Associated types do not help either. For example struct DateTime<Off: Offset> { dt: NaiveDateTime, st: Off::State, off: Off } wouldn't work (duh). It seems that we may have to accept that we should use different types for conversion (.with_offset(...)) and state (DateTime<...>).

Generic serialization support (e.g. rustc_serialize)

Working with structs that contain chrono types and should be sent over a wire or stored in a file is a bit of a pain at the moment, because one has to either

  • implement serialization for the entire struct manually, or
  • create separate 'serialization' structs that store date/time values as dumb integer timestamps and convert between those and the structs that the application actually uses internally

Is there a chance we can have some form of automatic serialization support in chrono? Maybe via rustc_serialize and the RustcEncodable, RustcDecodable traits? Or some other serialization library (serde has been mentioned here and there)?

This might raise some tricky questions because, for instance, serialization to JSON would be nicer if date/time values were formatted in an at least somewhat human readable form, whereas pure binary serialization, like with bincode would be more efficient with just the timestamp+tz as integers.

Datetime parser

Something like strptime. Not sure if it needs regex dependency.

Encoding/Decoding ISO-8601

What are your thoughts on serialization to and from ISO-8601 strings?

I'm looking to decode an API response with something along these lines:

#[derive(RustcDecodable)]
struct Foo {
  name: String,
  created_at: DateTime<UTC>, // or perhaps a type the Derefs into DateTime?
}

let json_str = r#"{name: "bar", "created_at": "2015-05-01T21:48:27.000Z"}"#;
let foo: Foo = json::decode(json_str).unwrap();

Currently such decode returns in Err(ExpectedError("Object", "\"2015-05-01T21:48:27.000Z\""))

Just trying to figure out if I'll be re-inventing the wheel, or if this is something that fits within the scope of Chrono.

Cannot parse date with DateTime::parse_from_str()

Hi,

I'm writing a taskwarrior hook library and I fail parsing the datetime objects I get from taskwarrior:

Output documentation for taskwarrior: https://taskwarrior.org/docs/design/task.html#type_date

The datetime object it exports look like this: "20120110T231200Z", the format is "YYYYMMDDTHHMMSSZ".

My example code:

    #[test]
    fn test_chrono() {
        let r = DateTime::parse_from_str("20150612T164806Z", "YYYYMMDDTHHMMSSZ");
        println!("{:?}", r);
        println!("{:?}", r.err().unwrap().description());
        assert!(false) // to get the error output
    }

It yields:

Err(ParseError(Invalid))
"input contains invalid characters"

But I do not get any further. What am I doing wrong?

UTC seems to be treated as canonical; hazardous in the presence of leap seconds

Chrono seems to treat UTC as the canonical/internal time representation, but this is hazardous because UTC includes leap seconds.

In your Jan 13 rustlog you bring up four issues regarding time zones:

  1. There is no reliable way to handle the local date in the future.
  2. There can exist a local date which occurred in two or more instants.
  3. There can exist a local date which never has been occurred.
  4. The conversion process itself is seriously annoying and easy to make a mistake.

The problem with UTC is that all four of those are true of it as well:

  1. Future leap seconds can be declared at any time, invalidating calculations of future datetimes
  2. Leap seconds as they have occurred so far result in a second that happens twice
  3. Leap seconds can (and eventually will) go in the other direction, resulting in seconds that never happen
  4. Leap second handling is oh so painfully annoying and easy to get wrong

I would suggest instead using TAI, which is the basis of UTC. (UTC is TAI with leap seconds)

DateTime objects cause panics at certain times of day

I'm not sure if this is chrono, or something I'm doing wrong, but an application I'm writing with the following code produces a panic at only certain times of day:

let format = arguments.value_of("format").unwrap_or("%H%d%m%Y");

let temp: i32 = Local::now().format(format).to_string().parse().unwrap();

I've noticed this in the evening, around 22:00. It produces this panic:

thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: Overflow }', ../src/libcore/result.rs:746

To try and figure out what was going on, I replaced the second line of code with

let temp: i32 = UTC.ymd(2016, 4, 21).and_hms(22, 0, 0).format(format).to_string().parse().unwrap();

and changed the 22 to various reasonable integers. It will always panic at 22, and sometimes panic at 20 and 21. It panicked at 23 when I tested it just now, but that was just once. It doesn't seem to panic at any other time, but more vigorous testing may prove otherwise.

Tzfile support

So that we don't have to separately ship something like pytz rely on the fragile, sometimes incorrect and unreliable OS APIs :)

Leapseconds are handled confusingly

extern crate chrono;

use chrono::{UTC, TimeZone, Timelike};

fn main() {
    let s = "100102030460Z";
    let d = UTC.datetime_from_str(s, "%y%m%d%H%M%SZ").unwrap();
    println!("{} -- second={}, nanosecond={}", d, d.second(), d.nanosecond());
}
/t/te (master) $ cargo run
     Running `target/debug/te`
2010-01-02 03:04:60 UTC -- second=59, nanosecond=1000000000

Specifically: the string representation of the datetime shows it (correctly) as :60 seconds, however the internal representation stores it as 59 seconds and 1000000000 nanoseconds. In general, smaller units are converted to larger ones as soon as an integral divisor is reached, so I'm not sure why it's not d.second() -> 60 and d.nanosecond() -> 0.

Consider using an HTML table for strftime format display

Specifically https://lifthrasiir.github.io/rust-chrono/chrono/format/strftime/index.html

rustdoc's markdown supports tables (similar to those that github supports), or one could use inline HTML.

e.g.

Spec. Example Description
%Y 2001 The full proleptic Gregorian year, zero-padded to 4 digits. Negative years are allowed in formatting but not in parsing.
%C 20 The proleptic Gregorian year divided by 100, zero-padded to 2 digits. This is floor division, so 100 BCE (year number -99) will print -1.
%y 01 The proleptic Gregorian year modulo 100, zero-padded to 2 digits. This is floor division, so 100 BCE (year number -99) will print 99.

Source:

| Spec. | Example | Description |
|---|---|---|
| `%Y` | `2001` | The full proleptic Gregorian year, zero-padded to 4 digits.  Negative years are allowed in formatting but not in parsing. |
| `%C `| `20` | The proleptic Gregorian year divided by 100, zero-padded to 2 digits. This is floor division, so 100 BCE (year number -99) will print `-1`. |
| `%y` | `01` | The proleptic Gregorian year modulo 100, zero-padded to 2 digits. This is floor division, so 100 BCE (year number -99) will print `99`. |

(Unfortunately, I don't know if it is possible to line break the source inside a tables for large cells.)

Add TAI timezone

Chrono currently uses UTC as canonical representation, with an optional positive leap second marking. This seems inevitable with the current OS support, but given sufficient data, we may want to handle TAI and UTC-SLS as well.

Depends on #10 (tzdata does have a leap second table); affected by #11.

Parser Error for time like 2015-12-08 04:21:28.000000

let valid_time_begin_string = rush_hour.valid_time_begin.clone().unwrap();
let valid_time_end_string = rush_hour.valid_time_end.clone().unwrap();
let valid_time_begin = NaiveDateTime::parse_from_str(&valid_time_begin_string, "%Y-%m-%d %H:%M:%S%f").ok();
let valid_time_end = NaiveDateTime::parse_from_str(&valid_time_end_string, "%Y-%m-%d %H:%M:%S").ok();

valid_time_begin format is yyyy-MM-dd HH:mm:ss.ffffff, using postgres database type TIMESTAMP WITHOUT TIME ZONE. Sometimes, the .ffffff will be .000000, but another times, it is .123123, it is random.
If i use NaiveDateTime::parse_from_str(&valid_time_begin_string, "%Y-%m-%d %H:%M:%S"), it
trigger error when time is like 2015-12-08 04:21:28.123456, when i use NaiveDateTime::parse_from_str(&valid_time_begin_string, "%Y-%m-%d %H:%M:%S%f"), it trigger error when time is like 2015-12-08 04:21:28.000000!

Relicense to MIT/ASL2

Rust is potentially going to pull Duration into mainline. Future such transitions will be easier if the licenses agree.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.