- Formatting item types are no longer `Copy`.
- `Numeric` and `Fixed` items now have `Internal` variants reserved
for the future expansion. It had been hard to expand the items
without totally breaking the backward compatibility (as per
the API evolution guideline of RFC 1105).
- `Item::Owned{Literal,Space}` for the owned variant of
`Item::{Literal,Space}` has been added.
Closes#76.
This may sound strange, but the final type for the offset "value" was
originally `time::Duration` (returned by `Offset::local_minus_utc`).
This caused a lot of problems becaus adding `Duration` fully interacts
with leap seconds and `Duration` itself is somewhat deprecated.
This commit entirely replaces this role of `Duration` with
`FixedOffset`. So if we had `Offset` and `Duration` to represent
the "storage" offset type and the offset "value" in the past,
we now have `Offset` and `FixedOffset`. Storage-to-value conversion is
called to "fix" the offset---an apt term for the type.
The list of actual changes:
- The time zone offset is now restricted to UTC-23:59:59 through
UTC+23:59:59, and no subsecond value is allowed. As described above,
`FixedOffset` is now fully used for this purpose.
- One can now add and subtract `FixedOffset` to/from timelike values.
Replaces a temporary `chrono::offset::add_with_leapsecond` function.
Datelike & non-timelike values are never affected by the offset.
- UTC and local views to `Date<Tz>` are now identical. We keep
relevant methods for the consistency right now.
- `chrono::format::format` now receives `FixedOffset` in place of
`(Old)Duration`.
- `Offset` now has a `fix` method to resolve, or to "fix" the
"storage" offset (`Offset`) to the offset "value" (`FixedOffset`).
- `FixedOffset::{local_minus_utc, utc_minus_local}` methods are added.
They no longer depend on `Duration` as well.
- Rustc-serialize now uses the same serialization format as Serde.
This also means that the older format (naturally derived from
the internals) is no longer supported.
- Serialization support only existed for rustc-serialize has been
(temporarily) removed. This affects `Date<Tz>` and all individual
time zone types. This does *not* affect `DateTime<Tz>` as it has
individual support per `Tz`.
Please note that this is considered a temporary solution to avoid
stabilizing diverging implementations. Their implementations will
likely be reintroduced later.
Due to the backward compatibility we won't be going to remove support
for `time::Duration` in 0.3, and the initial 0.3.0 release won't have
proper `std::time::Duration` support (haven't finalized the logics).
However we will reserve proper names and signatures for the upcoming
`std::time::Duration` support---the "older" duration type will be
referred as "signed" in the names.
- Added a `chrono::prelude` module. This does not have the (old)
`Duration` type reexported, so the documentation has now correctly
replaced all occurrences of `chrono::Duration`. The existing
`chrono::Duration` reexport itself remains for the compatibility.
- Avoided using a plain `Duration` type in the signature, to avoid
any ambiguity.
- Renamed `checked_{add,sub}` to `checked_{add,sub}_signed`.
- Subtraction operator between two instants has been removed and
replaced with `signed_duration_since`. This follows the naming
chosen by `std::time::SystemTime` etc., and the version for newer
`std::time::Duration` will be named to `duration_since`.
All CI accounts are now moved to the new organization (unfortunately
Appveyor does not automatically move the build history though).
Since it's a mess to redirect everything to chronotope.github.io,
I've taken this as an opportunity to switch to docs.rs---this seems
to be better than the manual management nowadays.
Updated other files as accordingly.
This provides examples for most of the constructor-like methods on
`TimeZone`, examples on the various `Offset` impls, and links
`NaiveDateTime` to `TimeZone` so that it's more obvious how you're
supposed to do things.
This is related to #88, which is something that I ran into when I
started using rust-chrono.
The ISO 8601 format includes both "nominal" (year, month, week, and
day) and "accurate" (hour, minute, and second) components. However, the
`Duration` type only represents an "accurate" duration because
arithmetic with nominal components is not defined in ISO 8601.
- `NaiveDateTime` is now almost completely annotated with examples.
- Introduced `NaiveTime::overflowing_{add,sub}` for the correct
handling of overflow/underflow of `NaiveTime`.
- `NaiveDateTime +/- Duration` operation is rewritten with those
methods, eliminating any problem against leap seconds. (Thus this
is yet another slight breaking change, but considered a bug fix.)
Especially for naives types, methods can be too long to fit in
one line. Previously ad-hoc closures have been used for extreme
cases; this commit will update them to the following form:
use anything::needs::to::be::imported;
let shortened = SomeType::long_name_to_be_shortened;
assert_eq!(shortened(...), ...);
It should be noted that the shortened name is no longer arbitrary;
it should be either the original method name, or when it gets too
long, a name with adjectives and clauses removed. The abbreviation
is now consistent, and restricted to the following:
- `num_days` -> `ndays`; `num_secs` -> `nsecs`
- `hms_milli` -> `hmsm`; - `hms_micro` -> `hmsu`; `hms_nano` -> `hmsn`
The goal is to make examples NOT look alike tests, and more alike
the actual code. (Well, not always possible but I'm trying.)
While writing documentation tests for NaiveTime it was found that
the addition involving leap seconds is *still* slightly broken.
(A consequence of having less tests, well.) The addition routine
has been rewritten to be explicit about leap seconds while passing
all other tests, so the rewrite does not change the intention.
- Serde 0.8 is now supported. (#86)
- The deserialization implementation for rustc-serialize now properly
verifies the input. Also tons of tests have been added. (#42)
For a while Chrono's serialization support was barely working,
i.e. usable but never been safe. While it wouldn't cause any memory
unsafety, attacker can fabricate an input that will make most users
confused (e.g. seemingly same Date which doesn't compare equally).
This commit will properly error for those cases.
It was also problematic that the generated rustc-serialize format is
very inefficient, especially for JSON. Due to the backward
compatibillity this commit does NOT fix them (likely to be in 0.3),
but this does try to define the exact format and define tons of
tests to detect any change to the serialization.
There are several remaining problems in the serialization format;
the serde implementation seems good, but it is unable to distinguish
some cases of leap seconds (practically won't matter, but still).
The rustc-serialize implementation would require a massive redesign.
For now, I postpone those issues to 0.3 (what a convenient excuse).
Fixes#42.
- Tons of documentation updates! (#77, #78, #80, #82 and my own
changes as well)
- `DateTime::timestamp_subsec_{millis,micros,nanos}` methods have
been added. (#81)
- When the system time records a leap second,
the nanosecond component was mistakenly reset to zero. (#84)
- `Local` offset misbehaves in Windows for August and later,
due to the long-standing libtime bug (dates back to mid-2015).
Workaround has been implemented. (#85)
In Windows libtime populate `time::Tm` from `SYSTEMTIME`, which
unfortunately does not contain `tm_yday`. It tries to calculate it
from other fields, but... as one can say it is completely wrong.
Since other fields are copied in verbatim we work around this
problem by using a less efficient method.
Fixes#85.
- The main documentation (`src/lib.rs` AND `README.md`) now properly
link to other types when rendered.
- The role of `TimeZone` trait is explained more thoroughly.
(Hopefully) fixes#82.
* Add functions to get milli/micro/nano-seconds from a DateTime
Using the underlying naive::NaiveTime fractional part, we compute
the number of milli/micro/nano-seconds since the last second boundary.
The reason for not computing elapsed time since 1970 is because we
would hit potential issues of i64s not being large enough (the range
would be strictly smaller than the 64bit-timestamp range, causing
compatibility issues).
* Rename subsecond functions
Renamed accessors to subsec_{nano,micro,milli}, as suggested
in pull request comment. Also added warnings for leap second
consitions causing these values to exceed the normal range
of 0..10^n.
Fixed editor's previous obnoxious whitespace changes.
- `%.6f` and `%.9f` used to print only three digits
when the nanosecond part is zero. (#71)
- The documentation for `%+` has been updated
to reflect the current status. (#71)
Although not supported directly by chrono, users should be able to
specify the RFC850 format and expect it to parse properly. RFC850 is
important since HTTP/1.1 specifies
HTTP-date = rfc1123-date | rfc850-date | asctime-date
- Added `%.3f`, `%.6f` and `%.9f` specifier for formatting fractional seconds
up to 3, 6 or 9 decimal digits. This is a natural extension to the existing `%f`.
Note that this is (not yet) generic, no other value of precision is supported. (#45)
- Forbade unsized types from implementing `Datelike` and `Timelike`.
This does not make a big harm as any type implementing them should be already sized
to be practical, but this change still can break highly generic codes. (#46)
- Fixed a broken link in the `README.md`. (#41)
- Tons of supporting examples for the documentation have been added. More to come.
The following warnings appear:
```
Compiling chrono v0.2.15 (file:///Users/coreyf/Development/rust/rust-chrono)
src/lib.rs:504:5: 504:52 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:504 fn with_year(&self, year: i32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:504:5: 504:52 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:504:5: 504:52 note: `Self` does not have a constant size known at compile-time
src/lib.rs:504 fn with_year(&self, year: i32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:504:5: 504:52 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:504 fn with_year(&self, year: i32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:504:5: 504:52 note: required by `core::option::Option`
src/lib.rs:504 fn with_year(&self, year: i32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:509:5: 509:54 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:509 fn with_month(&self, month: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:509:5: 509:54 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:509:5: 509:54 note: `Self` does not have a constant size known at compile-time
src/lib.rs:509 fn with_month(&self, month: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:509:5: 509:54 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:509 fn with_month(&self, month: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:509:5: 509:54 note: required by `core::option::Option`
src/lib.rs:509 fn with_month(&self, month: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:514:5: 514:56 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:514 fn with_month0(&self, month0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:514:5: 514:56 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:514:5: 514:56 note: `Self` does not have a constant size known at compile-time
src/lib.rs:514 fn with_month0(&self, month0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:514:5: 514:56 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:514 fn with_month0(&self, month0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:514:5: 514:56 note: required by `core::option::Option`
src/lib.rs:514 fn with_month0(&self, month0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:519:5: 519:50 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:519 fn with_day(&self, day: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:519:5: 519:50 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:519:5: 519:50 note: `Self` does not have a constant size known at compile-time
src/lib.rs:519 fn with_day(&self, day: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:519:5: 519:50 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:519 fn with_day(&self, day: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:519:5: 519:50 note: required by `core::option::Option`
src/lib.rs:519 fn with_day(&self, day: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:524:5: 524:52 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:524 fn with_day0(&self, day0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:524:5: 524:52 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:524:5: 524:52 note: `Self` does not have a constant size known at compile-time
src/lib.rs:524 fn with_day0(&self, day0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:524:5: 524:52 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:524 fn with_day0(&self, day0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:524:5: 524:52 note: required by `core::option::Option`
src/lib.rs:524 fn with_day0(&self, day0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:529:5: 529:58 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:529 fn with_ordinal(&self, ordinal: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:529:5: 529:58 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:529:5: 529:58 note: `Self` does not have a constant size known at compile-time
src/lib.rs:529 fn with_ordinal(&self, ordinal: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:529:5: 529:58 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:529 fn with_ordinal(&self, ordinal: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:529:5: 529:58 note: required by `core::option::Option`
src/lib.rs:529 fn with_ordinal(&self, ordinal: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:534:5: 534:60 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:534 fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:534:5: 534:60 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:534:5: 534:60 note: `Self` does not have a constant size known at compile-time
src/lib.rs:534 fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:534:5: 534:60 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:534 fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:534:5: 534:60 note: required by `core::option::Option`
src/lib.rs:534 fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:580:5: 580:52 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:580 fn with_hour(&self, hour: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:580:5: 580:52 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:580:5: 580:52 note: `Self` does not have a constant size known at compile-time
src/lib.rs:580 fn with_hour(&self, hour: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:580:5: 580:52 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:580 fn with_hour(&self, hour: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:580:5: 580:52 note: required by `core::option::Option`
src/lib.rs:580 fn with_hour(&self, hour: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:585:5: 585:53 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:585 fn with_minute(&self, min: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:585:5: 585:53 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:585:5: 585:53 note: `Self` does not have a constant size known at compile-time
src/lib.rs:585 fn with_minute(&self, min: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:585:5: 585:53 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:585 fn with_minute(&self, min: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:585:5: 585:53 note: required by `core::option::Option`
src/lib.rs:585 fn with_minute(&self, min: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:590:5: 590:53 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:590 fn with_second(&self, sec: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:590:5: 590:53 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:590:5: 590:53 note: `Self` does not have a constant size known at compile-time
src/lib.rs:590 fn with_second(&self, sec: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:590:5: 590:53 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:590 fn with_second(&self, sec: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:590:5: 590:53 note: required by `core::option::Option`
src/lib.rs:590 fn with_second(&self, sec: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:595:5: 595:58 warning: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
src/lib.rs:595 fn with_nanosecond(&self, nano: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:595:5: 595:58 help: run `rustc --explain E0277` to see a detailed explanation
src/lib.rs:595:5: 595:58 note: `Self` does not have a constant size known at compile-time
src/lib.rs:595 fn with_nanosecond(&self, nano: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:595:5: 595:58 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
src/lib.rs:595 fn with_nanosecond(&self, nano: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:595:5: 595:58 note: required by `core::option::Option`
src/lib.rs:595 fn with_nanosecond(&self, nano: u32) -> Option<Self>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
...because of:
https://github.com/rust-lang/rfcs/pull/1214
- Added padding modifiers `%_?`, `%-?` and `%0?`.
- Added new specifiers `%:z` and `%.f`.
- When `%s` specifier is used with a time zone, the time zone offset was
ignored. This has been fixed.
- Several documentation fixes including the misleading presence of
colons in the `%z` specifier. `%:z` was introduced partly due to this.
- Padding modifiers `%_?`, `%-?` and `%0?` are implemented.
They are glibc extensions which seem to be reasonably widespread
(e.g. Ruby).
- Added `%:z` specifier and corresponding formatting items
which is essentially same to `%z` but with a colon.
- Added a new specifier `%.f` which precision adapts from the input.
Also clearly documented the differences between `%f` and `%.f`. (#40)
- The time zone offset is printed without a colon, but the documentation
had that inverted. (#39)
- `chrono::format::strftime`'s specifier table is tested throughly.
- When `%s` specifier is used with a time zone, the time zone offset was
ignored. This has been fixed.
- `NaiveDateTime +/- Duration` or `NaiveTime +/- Duration` could
have gone wrong when the `Duration` to be added is negative and
has a fractional second part.
This was caused by an underflow in the conversion from `Duration`
to the parts; the lack of tests for this case allowed a bug.
A regression test has been added to avoid further bugs. (#37)
The exact condition is that the `Duration` to be added is negative
and has a fractional second part. This was not a problem when
`Duration` was Chrono's own type, but a new code for external (then
libstd, now libtime) `Duration` was not tested for this condition
by accident. Consequently this condition caused an underflow in
the fractional part, resulting in a slight inaccuracy.
Fixes#37.
- This version is finally beta-compatible.
This introduces a slight incompatibility, namely, due to
the rewired reexport for `chrono::Duration` (which now comes
from crates.io `time` crate).
- The optional dependency on `rustc_serialize` and relevant
`Rustc{En,De}codable` implementations for supported types
has been added. You will need the `rustc-serialize` Cargo
feature to use them.
- Many `std::num` traits are removed and replaced with
the external `num` crate. For time being, thus, Chrono will
require the dependency on `num`. This is expected to be temporary
however.
- Replaced `thread::scoped` with `thread::spawn` to cope with
a rare de-stabilization event.
- `#[deprecated]` is (ironically) deprecated with user crates.
All uses of them have been replaced by doc comments.
- Feature flags are now required on the doctests.
- New lints for trivial casts. We are now not going to change
the internal implementation type for `NaiveDate`, so that's fine.
This is due to somewhat ambiguous semantics of `Date`. It cannot
really constructed without an intermediate `DateTime` much like
the removed `Time`, but it is much more useful than `Time` so
we need some reasonable meaning to it. This commit clarifies
that meaning and corrects some problems around it:
- The date itself is timezone-agnostic unless the timezone itself
has an offset equal to or greater than one day. In all current
time zones, the date conversion should be a no-op.
- The date may be attached some offset; that offset should have
been occurred within the corresponding day in either the local
time or the UTC.
- `TimeZone` is free to assign the offset within this constraint.
For convenience, the current `Local` time zone assumes the local
midnight or the UTC midnight.
- `DateTime<Tz>` and `Date<Tz>` is now `Copy`/`Send` when
`Tz::Offset` is `Copy`/`Send`. The implementations for them were
mistakenly omitted. Fixes#25.
- `Local::from_utc_datetime` didn't set a correct offset.
The tests for `Local` were lacking. Fixes#26.
`Time` with an associated time zone is in principle possible, but
in practice it can only meaningfully constructed from an existing
`DateTime`. this makes it hard to implement other operations
natural to `NaiveTime` for `Time` (e.g. `with_*` methods), so
we simply let it go.
migration path: if you *do* happen to use `Time`, don't panic!
every operation possible to `Time` is much more possible to
`NaiveTime`. if you have to deal with a local time, first combine
it with a `NaiveDate`, convert it via `TimeZone::from_local_datetime`
then extract `Time` part again.
this is partly because... we are using the simple name `timestamp`
in the `Parsed` anyway. that value is so widespread enough that
its name can be simply THE timestamp. old methods have been marked
deprecated.
- We have splitted `Offset` into `Offset` and `OffsetState` (name
changes in consideration). The former is used to construct and convert
local or UTC date, and the latter is used to store the UTC offset
inside constructed values. Some offsets are their own states as well.
- This uses lots of associated types which implementation is still in
flux. Currently it crashes with debuginfo enabled. We've temporarily
disabled debuginfo from `Cargo.toml`.
- This technically allows a conversion to the local time, but not yet
tested.
also, previously `Numeric::Nanosecond` had a special left-aligned
parsing behavior. this commit replaces that with a newly designated
`Fixed::Nanosecond` which also handles an empty string which is
possible with an integral number of seconds.
this is most importantly required for negative years in `Parsed`,
which the current parser doesn't generate but is nevertheless
possible in principle. also updates tests for new fields.
so that we can safely implement `FromStr` traits for those types.
also updates READMEs and rewires `%+` specifier of `StrftimeItems`
to a new RFC 3339 formatting item.
this new module encompasses John Nagle's original RFC 2822 and 3337
parsers, updated to fully compatible to the actual standard.
the contributed `parse` module has been merged into it.
also changes the behavior of `Numeric::Nanosecond` (`%f`) to
the left-aligned digits and allows for the wider range of time zone
offsets from -99:59 to +99:59.
Basically, this should close#12 when officially released.
- Formatting syntax is now refactored out of the rendering logic.
The main syntax is available in the `format::strftime` module,
which also serves as a documentation for the syntax.
- A parser (modelled after `strptime(3)`) has been implemented.
See the individual commits for the detailed implementation.
- There are two ways to get a timezone-aware value from a string:
`Offset` or `DateTime<FixedOffset>`. The former should be used
when the offset is known in advance (e.g. assume the local date)
while the latter should be used when the offset is unknown.
Naive types have a simple `from_str` method.
- There are some known problems with the parser (even after
tons of tests), which will be sorted out in 0.2. Known issues:
- This does not exactly handle RFC 2822 and RFC 3339, which
subtly differs from the current implementation in
case-sensitivity, whitespace handling and legacy syntax.
I'd like to integrate #24 for this cause.
- Time zone names are not recognized at all. There is even
no means to get a name itself, not sure about the resolution.
- `Parsed` does *not* constrain `year` to be non-negative,
so manually prepared `Parsed` may give a negative year.
But the current verification pass may break such cases.
- I absolutely don't know about the parser's performance!
- `AUTHORS.txt` has been added, for what it's worth.
- Format string is internally represented as a series of formatting
items. Items can be directly given to now-public `format::format`
function as well.
- Format string parser is separated to `format::strftime` module.
This is to allow for potentional alternative formatting syntaxes.
- `DelayedFormat` now receives an iterator for formatting items.
- Every type modulo `LocalResult` and `Offset` now implements
`std::fmt::String`, so `.to_string()` can be used.
The exact format has been changed for better looking output.
- `std::fmt::Show` are intended for "stricter" output,
which mostly means the strict ISO 8601 format.
`DelayedFormat` also implements this, but only for inspection.
- `Offset` should implement `Show` but can omit `String`.
The old `name` method is merged into `String` implementations.
- Feature flags used are all accepted.
- Orphan check workaround is no longer required.
- Impl reachability rules prevent the addition of `Duration + others`,
as `Duration` is not implemented in this crate. Removed the impl;
use `others + Duration` as a workaround.
- #[deriving] is now #[derive].
- prelude no longer imports many items by default.
- [T, ..n] is no longer valid.
- a temporary fix for #[derive(Hash)] failing out.
- the formatting error uses a dedicated type instead of `IoError`.
Added 'use' statements for cmd::Ordering, ops::{Add, Sub}, borrow::IntoCow, num::ToPrimitive
Changed deriving -> derive. Changed [x, ..N] -> [x; N].
Made format(f: &fmt::Formatter) return fmt::Result instead of
IoResult. Had to raise generic errors in a couple of cases where
IoResult's fields were being set (but these errors were being thrown
out anyway).
Temporarily set #![feature(old_orphan_check)] because
Thanks for @eddyb for explaining the format() situation.
- `Date/Time - Duration` is now supported. (duh!)
- `with_offset` methods have been added.
- `LocalResult` now implements common traits.
- `LocalResult` has several methods to propagate errors.
this makes the initialization from untrusted sources easier
(`off.ymd_opt(y,m,d).and_hms_opt(h,n,s).single()`).
- `num` dependency is gone. It was only used for floored division
and it is not hard to copy only that portion from num.
- `Duration + Date` (or so) was blocked by rust-lang/rust#7590,
which has been subsequently fixed.
- Removed unused `unsafe` checks.
- `std::fmt::WriteError` is now `std::fmt::Error`.
- abandoned rust-ci for documentations (sorry, but it didn't work
nowdays ;_;), we are now publishing directly to Github pages.
`Duration` now has a `to_tuple` method which corresponds to
the original `(dur.ndays(), dur.nseconds(), dur.nnanoseconds())`.
new `num_*s()` methods in `Duration` always return the integral
number of specified units in the duration.
cf. rust-lang/rust#15934
ISO 8601 allows for both but prefers `,`, which was a main reason
for its use in rust-chrono. but this is too alien given other usages of
decimal points in Rust, so I guess it is better to switch to `.`.
the minimum and maximum for `DateZ` and `Duration` is now provided via
dedicated constants `{date,duration}::{MIN,MAX}`, much like built-in
`std::int` and others. they also now implements `std::num::Bounded`.
cf. rust-lang/rust#15934
- added a new example.
- reexported all public APIs in the crate root.
- made all constructors fail on the invalid arguments by default;
`*_opt()` variants have been added for the original behavior.
- same for `DateZ::{succ,pred}`.
- fixed a missing overflow check from `TimeZ::from_hms_{milli,micro}`.