chronotope / chrono Goto Github PK
View Code? Open in Web Editor NEWDate and time library for Rust
License: Other
Date and time library for Rust
License: Other
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.
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.
It'd be nice to offer Hash
implementations for all of the date/time structs so that they can be used as keys in HashMap
s.
RIght now the state of things is rather weird, where there are two different Duration types.
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.
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.).
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)
And it would be great to have such conversions!
I would like to have the ability to get the amount of milliseconds (or maybe even nanoseconds) since unix epoch.
Currently, this seems to only be available in seconds:
https://lifthrasiir.github.io/rust-chrono/chrono/datetime/struct.DateTime.html#method.timestamp
Is there a reason not to provide two extra methods like?
timestamp_milliseconds
timestamp_nanoseconds
If it is indeed desired, I can open a PR to add them.
Please let me know.
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?
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...
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
This is a proposal to add period and interval concepts like those used in Joda Time
cf.
http://www.joda.org/joda-time/key_period.html
http://www.joda.org/joda-time/key_interval.html
Those are distinct from but interoperable with the existing duration type, and make it possible to describe operations like "add 1 year to this date" (this might be a different number of seconds depending on the date)
Is this something that you would consider for this library?
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:
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.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.
Rust 1.8 stabilized assignment operator such as +=
and -=
I think they would fit the API nicely.
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
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.
#[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());
}
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".
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.
Currently I can parse date like "2014-03-10 11:20:34"
. Anyway if I need also parse milliseconds, I'm out of luck.
It would be great to be able to parse milliseconds. Something like UTC.datetime_from_str("2014-11-28 12:00:09.123", "%Y-%m-%d %H:%M:%S.%F")
(the original question is at http://stackoverflow.com/q/31126366/75224 )
The Complete Documentation link (http://rust-ci.org/lifthrasiir/rust-chrono/doc/chrono/) 404s. From this page it appears that documentation for the num
crate were built but no others.
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 Offset
s.
There are two ways of converting the offset of the date/time object:
datetime.replace(tzinfo=new_tz)
. The duration between the result and the original will be same as a distance of their offsets.datetime.astimezone(new_tz)
. They should have same UTC timestamp that the result and the original.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()
).
This works:
DateTime::parse_from_str("2014-09-17 00:00:00 +10:00", "%F %T %z")
But this gives a ParseError(BadFormat):
DateTime::parse_from_str("2014-09-17 00:00:00 AEDT", "%F %T %Z")
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 Clone
able 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.
I think it'd be helpful to point at the rust-ci location of the documentation, since you're going through the work of uploading it in your travis ci configuration. The url is http://rust-ci.org/lifthrasiir/rust-chrono/doc/chrono/
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
.
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)
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<...>
).
Would it be viable to implement the Default
trait for DateTime<FixedOffset>
?
Adding this in would be very useful for deserializing AWS responses in the rusoto project.
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
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.
Something like strptime
. Not sure if it needs regex
dependency.
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.
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?
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:
The problem with UTC is that all four of those are true of it as well:
I would suggest instead using TAI, which is the basis of UTC. (UTC is TAI with leap seconds)
Building from your git works fine though.
Cheers
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.
Those types aren't really designed for general arithmetic use (they vary per-platform), a fixed sized type is preferable.
E.g. https://github.com/lifthrasiir/rust-chrono/blob/11b2a10247bcfb5b06ba051368642238c9eb4ecb/src/chrono/duration.rs#L30 could just take i32
and u32
to match the struct it is creating.
So that we don't have to separately ship something like pytz rely on the fragile, sometimes incorrect and unreliable OS APIs :)
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
.
Reported via http://stackoverflow.com/questions/28747694/how-do-i-convert-a-chrono-datetimeutc-instance-to-datetimelocal. It does set a correct local date and time but not an offset, and is effectively same to UTC::from_utc_datetime
.
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.)
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!
Rust is potentially going to pull Duration
into mainline. Future such transitions will be easier if the licenses agree.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.