diff -Nru rust-chrono-0.4.6/appveyor.yml rust-chrono-0.4.7/appveyor.yml --- rust-chrono-0.4.6/appveyor.yml 2018-08-25 20:45:32.000000000 +0000 +++ rust-chrono-0.4.7/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -environment: - matrix: - - TARGET: 1.13.0-x86_64-pc-windows-gnu - - TARGET: nightly-x86_64-pc-windows-msvc - - TARGET: nightly-i686-pc-windows-msvc - - TARGET: nightly-x86_64-pc-windows-gnu - - TARGET: nightly-i686-pc-windows-gnu -matrix: - allow_failures: - - channel: nightly -install: - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}.exe" -FileName "rust-install.exe" - - ps: .\rust-install.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null - - ps: $env:PATH="$env:PATH;C:\rust\bin" - - rustc -vV - - cargo -vV - -build: false - -test_script: - - sh -c 'PATH=`rustc --print sysroot`/bin:$PATH ./ci/travis.sh' diff -Nru rust-chrono-0.4.6/Cargo.toml rust-chrono-0.4.7/Cargo.toml --- rust-chrono-0.4.6/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ rust-chrono-0.4.7/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,8 +12,9 @@ [package] name = "chrono" -version = "0.4.6" +version = "0.4.7" authors = ["Kang Seonghoon ", "Brandon W Maister "] +exclude = ["/ci/*", "/.travis.yml", "/appveyor.yml", "/Makefile"] description = "Date and time library for Rust" homepage = "https://github.com/chronotope/chrono" documentation = "https://docs.rs/chrono/" @@ -30,6 +31,10 @@ [lib] name = "chrono" +[dependencies.libc] +version = "0.2" +default-features = false + [dependencies.num-integer] version = "0.1.36" default-features = false @@ -52,6 +57,9 @@ [dev-dependencies.bincode] version = "0.8.0" +[dev-dependencies.doc-comment] +version = "0.3" + [dev-dependencies.num-iter] version = "0.1.35" default-features = false diff -Nru rust-chrono-0.4.6/Cargo.toml.orig rust-chrono-0.4.7/Cargo.toml.orig --- rust-chrono-0.4.6/Cargo.toml.orig 2018-08-25 20:45:57.000000000 +0000 +++ rust-chrono-0.4.7/Cargo.toml.orig 2019-06-25 00:54:56.000000000 +0000 @@ -1,6 +1,6 @@ [package] name = "chrono" -version = "0.4.6" +version = "0.4.7" authors = [ "Kang Seonghoon ", "Brandon W Maister ", @@ -14,6 +14,7 @@ categories = ["date-and-time"] readme = "README.md" license = "MIT/Apache-2.0" +exclude = ["/ci/*", "/.travis.yml", "/appveyor.yml", "/Makefile"] [badges] travis-ci = { repository = "chronotope/chrono" } @@ -27,6 +28,7 @@ clock = ["time"] [dependencies] +libc = { version = "0.2", default-features = false } time = { version = "0.1.39", optional = true } num-integer = { version = "0.1.36", default-features = false } num-traits = { version = "0.2", default-features = false } @@ -38,6 +40,7 @@ serde_derive = { version = "1" } bincode = { version = "0.8.0" } num-iter = { version = "0.1.35", default-features = false } +doc-comment = "0.3" [package.metadata.docs.rs] all-features = true diff -Nru rust-chrono-0.4.6/.cargo_vcs_info.json rust-chrono-0.4.7/.cargo_vcs_info.json --- rust-chrono-0.4.6/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 +++ rust-chrono-0.4.7/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,5 @@ +{ + "git": { + "sha1": "d8c68f6bd095e3db295d63439f2527f2b74de956" + } +} diff -Nru rust-chrono-0.4.6/CHANGELOG.md rust-chrono-0.4.7/CHANGELOG.md --- rust-chrono-0.4.6/CHANGELOG.md 2018-07-28 21:11:10.000000000 +0000 +++ rust-chrono-0.4.7/CHANGELOG.md 2019-06-21 21:10:49.000000000 +0000 @@ -6,7 +6,29 @@ Chrono obeys the principle of [Semantic Versioning](http://semver.org/). There were/are numerous minor versions before 1.0 due to the language changes. -Versions with only mechnical changes will be omitted from the following list. +Versions with only mechanical changes will be omitted from the following list. + +## 0.4.7 + +### Fixes + +* Disable libc default features so that CI continues to work on rust 1.13 +* Fix panic on negative inputs to timestamp_millis (@cmars #292) +* Make `LocalResult` `Copy/Eq/Hash` + +### Features + +* Add `std::convert::From` conversions between the different timezone formats + (@mqudsi #271) +* Add `timestamp_nanos` methods (@jean-airoldie #308) +* Documentation improvements + +## 0.4.6 + +### Maintenance + +* Doc improvements -- improve README CI verification, external links +* winapi upgrade to 0.3 ## 0.4.5 diff -Nru rust-chrono-0.4.6/ci/fix-readme.sh rust-chrono-0.4.7/ci/fix-readme.sh --- rust-chrono-0.4.6/ci/fix-readme.sh 2018-08-25 20:45:32.000000000 +0000 +++ rust-chrono-0.4.7/ci/fix-readme.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -#!/bin/bash - -VERSION="$( cargo read-manifest | python -c 'import json, sys; print(json.load(sys.stdin)["version"])')" -LIB="$1" - -# Make the Chrono in the header a link to the docs -awk '/^\/\/! # Chrono: / { print "[Chrono][docsrs]:", substr($0, index($0, $4))}' "$LIB" -awk '/^\/\/! # Chrono: / { print "[Chrono][docsrs]:", substr($0, index($0, $4))}' "$LIB" | sed 's/./=/g' -# Add all the badges -echo ' -[![Chrono on Travis CI][travis-image]][travis] -[![Chrono on Appveyor][appveyor-image]][appveyor] -[![Chrono on crates.io][cratesio-image]][cratesio] -[![Chrono on docs.rs][docsrs-image]][docsrs] -[![Join the chat at https://gitter.im/chrono-rs/chrono][gitter-image]][gitter] - -[travis-image]: https://travis-ci.org/chronotope/chrono.svg?branch=master -[travis]: https://travis-ci.org/chronotope/chrono -[appveyor-image]: https://ci.appveyor.com/api/projects/status/2ia91ofww4w31m2w/branch/master?svg=true -[appveyor]: https://ci.appveyor.com/project/chronotope/chrono -[cratesio-image]: https://img.shields.io/crates/v/chrono.svg -[cratesio]: https://crates.io/crates/chrono -[docsrs-image]: https://docs.rs/chrono/badge.svg -[docsrs]: https://docs.rs/chrono -[gitter-image]: https://badges.gitter.im/chrono-rs/chrono.svg -[gitter]: https://gitter.im/chrono-rs/chrono' - -# print the section between the header and the usage -awk '/^\/\/! # Chrono:/,/^\/\/! ## /' "$LIB" | cut -b 5- | grep -v '^#' | \ - sed 's/](\.\//](https:\/\/docs.rs\/chrono\/'$VERSION'\/chrono\//g' -echo -# Replace relative doc links with links to this exact version of docs on -# docs.rs -awk '/^\/\/! ## /,!/^\/\/!/' "$LIB" | cut -b 5- | grep -v '^# ' | \ - sed 's/](\.\//](https:\/\/docs.rs\/chrono\/'$VERSION'\/chrono\//g' \ diff -Nru rust-chrono-0.4.6/ci/travis.sh rust-chrono-0.4.7/ci/travis.sh --- rust-chrono-0.4.6/ci/travis.sh 2018-08-25 20:45:32.000000000 +0000 +++ rust-chrono-0.4.7/ci/travis.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -#!/bin/bash - -# This is the script that's executed by travis, you can run it yourself to run -# the exact same suite - -set -e - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -channel() { - if [ -n "${TRAVIS}" ]; then - if [ "${TRAVIS_RUST_VERSION}" = "${CHANNEL}" ]; then - pwd - (set -x; cargo "$@") - fi - elif [ -n "${APPVEYOR}" ]; then - if [ "${APPVEYOR_RUST_CHANNEL}" = "${CHANNEL}" ]; then - pwd - (set -x; cargo "$@") - fi - else - pwd - (set -x; cargo "+${CHANNEL}" "$@") - fi -} - -build_and_test() { - # interleave building and testing in hope that it saves time - # also vary the local time zone to (hopefully) catch tz-dependent bugs - # also avoid doc-testing multiple times---it takes a lot and rarely helps - cargo clean - channel build -v - TZ=ACST-9:30 channel test -v --lib - channel build -v --features rustc-serialize - TZ=EST4 channel test -v --features rustc-serialize --lib - channel build -v --features serde - TZ=UTC0 channel test -v --features serde --lib - channel build -v --features serde,rustc-serialize - TZ=Asia/Katmandu channel test -v --features serde,rustc-serialize - - # without default "clock" feature - channel build -v --no-default-features - TZ=ACST-9:30 channel test -v --no-default-features --lib - channel build -v --no-default-features --features rustc-serialize - TZ=EST4 channel test -v --no-default-features --features rustc-serialize --lib - channel build -v --no-default-features --features serde - TZ=UTC0 channel test -v --no-default-features --features serde --lib - channel build -v --no-default-features --features serde,rustc-serialize - TZ=Asia/Katmandu channel test -v --no-default-features --features serde,rustc-serialize --lib - - if [[ "$CHANNEL" == stable ]]; then - if [[ -n "$TRAVIS" ]] ; then - check_readme - fi - fi -} - -build_only() { - # Rust 1.13 doesn't support custom derive, so, to avoid doctests which - # validate that, we just build there. - cargo clean - channel build -v - channel build -v --features rustc-serialize - channel build -v --features 'serde bincode' - channel build -v --no-default-features -} - -run_clippy() { - # cached installation will not work on a later nightly - if [ -n "${TRAVIS}" ] && ! cargo install clippy --debug --force; then - echo "COULD NOT COMPILE CLIPPY, IGNORING CLIPPY TESTS" - exit - fi - - cargo clippy --features 'serde bincode rustc-serialize' -- -Dclippy -} - -check_readme() { - make readme - (set -x; git diff --exit-code -- README.md) ; echo $? -} - -rustc --version -cargo --version - -CHANNEL=nightly -if [ "x${CLIPPY}" = xy ] ; then - run_clippy -else - build_and_test -fi - -CHANNEL=beta -build_and_test - -CHANNEL=stable -build_and_test - -CHANNEL=1.13.0 -build_only diff -Nru rust-chrono-0.4.6/debian/cargo-checksum.json rust-chrono-0.4.7/debian/cargo-checksum.json --- rust-chrono-0.4.6/debian/cargo-checksum.json 2018-12-11 05:51:27.000000000 +0000 +++ rust-chrono-0.4.7/debian/cargo-checksum.json 2019-07-10 17:15:38.000000000 +0000 @@ -1 +1 @@ -{"package":"45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878","files":{}} +{"package":"Could not get crate checksum","files":{}} diff -Nru rust-chrono-0.4.6/debian/changelog rust-chrono-0.4.7/debian/changelog --- rust-chrono-0.4.6/debian/changelog 2018-12-11 05:51:27.000000000 +0000 +++ rust-chrono-0.4.7/debian/changelog 2019-07-10 17:15:38.000000000 +0000 @@ -1,3 +1,9 @@ +rust-chrono (0.4.7-1) unstable; urgency=medium + + * Package chrono 0.4.7 from crates.io using debcargo 2.3.1-alpha.0 + + -- Wolfgang Silbermayr Wed, 10 Jul 2019 19:15:38 +0200 + rust-chrono (0.4.6-1) unstable; urgency=medium * Package chrono 0.4.6 from crates.io using debcargo 2.2.9 diff -Nru rust-chrono-0.4.6/debian/control rust-chrono-0.4.7/debian/control --- rust-chrono-0.4.6/debian/control 2018-12-11 05:51:27.000000000 +0000 +++ rust-chrono-0.4.7/debian/control 2019-07-10 17:15:38.000000000 +0000 @@ -2,10 +2,11 @@ Section: rust Priority: optional Build-Depends: debhelper (>= 11), - dh-cargo (>= 10), + dh-cargo (>= 18), cargo:native , rustc:native , libstd-rust-dev , + librust-libc-0.2-dev , librust-num-integer-0.1-dev (>= 0.1.36-~~) , librust-num-traits-0.2-dev , librust-time-0.1+default-dev (>= 0.1.39-~~) @@ -22,18 +23,18 @@ Multi-Arch: same Depends: ${misc:Depends}, + librust-libc-0.2-dev, librust-num-integer-0.1-dev (>= 0.1.36-~~), librust-num-traits-0.2-dev Recommends: librust-chrono+clock-dev (= ${binary:Version}) Suggests: librust-chrono+rustc-serialize-dev (= ${binary:Version}), - librust-chrono+serde-dev (= ${binary:Version}), - librust-chrono+time-dev (= ${binary:Version}) + librust-chrono+serde-dev (= ${binary:Version}) Provides: librust-chrono-0-dev (= ${binary:Version}), librust-chrono-0.4-dev (= ${binary:Version}), - librust-chrono-0.4.6-dev (= ${binary:Version}) + librust-chrono-0.4.7-dev (= ${binary:Version}) Description: Date and time library for Rust - Rust source code This package contains the source for the Rust chrono crate, packaged by debcargo for use with cargo and dh-cargo. @@ -47,15 +48,21 @@ librust-time-0.1+default-dev (>= 0.1.39-~~) Provides: librust-chrono+default-dev (= ${binary:Version}), + librust-chrono+time-dev (= ${binary:Version}), librust-chrono-0+clock-dev (= ${binary:Version}), librust-chrono-0+default-dev (= ${binary:Version}), + librust-chrono-0+time-dev (= ${binary:Version}), librust-chrono-0.4+clock-dev (= ${binary:Version}), librust-chrono-0.4+default-dev (= ${binary:Version}), - librust-chrono-0.4.6+clock-dev (= ${binary:Version}), - librust-chrono-0.4.6+default-dev (= ${binary:Version}) -Description: Date and time library for Rust - feature "clock" - This metapackage enables feature clock for the Rust chrono crate, by pulling in - any additional dependencies needed by that feature. + librust-chrono-0.4+time-dev (= ${binary:Version}), + librust-chrono-0.4.7+clock-dev (= ${binary:Version}), + librust-chrono-0.4.7+default-dev (= ${binary:Version}), + librust-chrono-0.4.7+time-dev (= ${binary:Version}) +Description: Date and time library for Rust - feature "clock" and 2 more + This metapackage enables feature "clock" for the Rust chrono crate, by pulling + in any additional dependencies needed by that feature. + . + Additionally, this package also provides the "default", and "time" features. Package: librust-chrono+rustc-serialize-dev Architecture: any @@ -67,10 +74,10 @@ Provides: librust-chrono-0+rustc-serialize-dev (= ${binary:Version}), librust-chrono-0.4+rustc-serialize-dev (= ${binary:Version}), - librust-chrono-0.4.6+rustc-serialize-dev (= ${binary:Version}) + librust-chrono-0.4.7+rustc-serialize-dev (= ${binary:Version}) Description: Date and time library for Rust - feature "rustc-serialize" - This metapackage enables feature rustc-serialize for the Rust chrono crate, by - pulling in any additional dependencies needed by that feature. + This metapackage enables feature "rustc-serialize" for the Rust chrono crate, + by pulling in any additional dependencies needed by that feature. Package: librust-chrono+serde-dev Architecture: any @@ -82,22 +89,7 @@ Provides: librust-chrono-0+serde-dev (= ${binary:Version}), librust-chrono-0.4+serde-dev (= ${binary:Version}), - librust-chrono-0.4.6+serde-dev (= ${binary:Version}) + librust-chrono-0.4.7+serde-dev (= ${binary:Version}) Description: Date and time library for Rust - feature "serde" - This metapackage enables feature serde for the Rust chrono crate, by pulling in - any additional dependencies needed by that feature. - -Package: librust-chrono+time-dev -Architecture: any -Multi-Arch: same -Depends: - ${misc:Depends}, - librust-chrono-dev (= ${binary:Version}), - librust-time-0.1+default-dev (>= 0.1.39-~~) -Provides: - librust-chrono-0+time-dev (= ${binary:Version}), - librust-chrono-0.4+time-dev (= ${binary:Version}), - librust-chrono-0.4.6+time-dev (= ${binary:Version}) -Description: Date and time library for Rust - feature "time" - This metapackage enables feature time for the Rust chrono crate, by pulling in - any additional dependencies needed by that feature. + This metapackage enables feature "serde" for the Rust chrono crate, by pulling + in any additional dependencies needed by that feature. diff -Nru rust-chrono-0.4.6/debian/copyright rust-chrono-0.4.7/debian/copyright --- rust-chrono-0.4.6/debian/copyright 2018-12-11 05:51:27.000000000 +0000 +++ rust-chrono-0.4.7/debian/copyright 2019-07-10 17:15:38.000000000 +0000 @@ -7,8 +7,8 @@ Files: * Copyright: - 2014-2018 Kang Seonghoon - 2017-2018 Brandon W Maister + 2014-2019 Kang Seonghoon + 2017-2019 Brandon W Maister License: MIT or Apache-2.0 Files: ./src/div.rs @@ -25,8 +25,8 @@ Files: debian/* Copyright: - 2018 Debian Rust Maintainers - 2018 Wolfgang Silbermayr + 2018-2019 Debian Rust Maintainers + 2018-2019 Wolfgang Silbermayr License: MIT or Apache-2.0 License: Apache-2.0 diff -Nru rust-chrono-0.4.6/debian/copyright.debcargo.hint rust-chrono-0.4.7/debian/copyright.debcargo.hint --- rust-chrono-0.4.6/debian/copyright.debcargo.hint 2018-12-11 05:51:27.000000000 +0000 +++ rust-chrono-0.4.7/debian/copyright.debcargo.hint 2019-07-10 17:15:38.000000000 +0000 @@ -48,8 +48,8 @@ Files: debian/* Copyright: - 2018 Debian Rust Maintainers - 2018 Wolfgang Silbermayr + 2018-2019 Debian Rust Maintainers + 2018-2019 Wolfgang Silbermayr License: MIT or Apache-2.0 License: Apache-2.0 diff -Nru rust-chrono-0.4.6/debian/tests/control rust-chrono-0.4.7/debian/tests/control --- rust-chrono-0.4.6/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ rust-chrono-0.4.7/debian/tests/control 2019-07-10 17:15:38.000000000 +0000 @@ -0,0 +1,19 @@ +Test-Command: /usr/share/cargo/bin/cargo-auto-test chrono 0.4.7 --all-targets --all-features +Depends: dh-cargo (>= 18), librust-bincode-0.8+default-dev, librust-doc-comment-0.3+default-dev, librust-num-iter-0.1-dev (>= 0.1.35-~~), librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test chrono 0.4.7 --all-targets --no-default-features +Depends: dh-cargo (>= 18), librust-bincode-0.8+default-dev, librust-doc-comment-0.3+default-dev, librust-num-iter-0.1-dev (>= 0.1.35-~~), librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, librust-chrono-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test chrono 0.4.7 --all-targets --features clock +Depends: dh-cargo (>= 18), librust-bincode-0.8+default-dev, librust-doc-comment-0.3+default-dev, librust-num-iter-0.1-dev (>= 0.1.35-~~), librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, librust-chrono+clock-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test chrono 0.4.7 --all-targets --features rustc-serialize +Depends: dh-cargo (>= 18), librust-bincode-0.8+default-dev, librust-doc-comment-0.3+default-dev, librust-num-iter-0.1-dev (>= 0.1.35-~~), librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, librust-chrono+rustc-serialize-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test chrono 0.4.7 --all-targets --features serde +Depends: dh-cargo (>= 18), librust-bincode-0.8+default-dev, librust-doc-comment-0.3+default-dev, librust-num-iter-0.1-dev (>= 0.1.35-~~), librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, librust-chrono+serde-dev +Restrictions: allow-stderr, skip-not-installable diff -Nru rust-chrono-0.4.6/Makefile rust-chrono-0.4.7/Makefile --- rust-chrono-0.4.6/Makefile 2018-08-25 20:45:32.000000000 +0000 +++ rust-chrono-0.4.7/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# this Makefile is mostly for the packaging convenience. -# casual users should use `cargo` to retrieve the appropriate version of Chrono. - -.PHONY: all -all: - @echo 'Try `cargo build` instead.' - -.PHONY: authors -authors: - echo 'Chrono is mainly written by Kang Seonghoon ,' > AUTHORS.txt - echo 'and also the following people (in ascending order):' >> AUTHORS.txt - echo >> AUTHORS.txt - git log --format='%aN <%aE>' | grep -v 'Kang Seonghoon' | sort -u >> AUTHORS.txt - -.PHONY: readme README.md -readme: README.md - -README.md: src/lib.rs - ( ./ci/fix-readme.sh $< ) > $@ - -.PHONY: test -test: - TZ=UTC0 cargo test --features 'serde rustc-serialize bincode' --lib - TZ=ACST-9:30 cargo test --features 'serde rustc-serialize bincode' --lib - TZ=EST4 cargo test --features 'serde rustc-serialize bincode' - -.PHONY: doc -doc: authors readme - cargo doc --features 'serde rustc-serialize bincode' - diff -Nru rust-chrono-0.4.6/README.md rust-chrono-0.4.7/README.md --- rust-chrono-0.4.6/README.md 2018-08-25 20:46:44.000000000 +0000 +++ rust-chrono-0.4.7/README.md 2019-06-21 21:49:37.000000000 +0000 @@ -82,7 +82,7 @@ months. Chrono does not yet natively support -the standard [`Duration`](https://docs.rs/time/0.1.40/time/struct.Duration.html) type, +the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type, but it will be supported in the future. Meanwhile you can convert between two types with [`Duration::from_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.from_std) @@ -93,7 +93,7 @@ ### Date and Time Chrono provides a -[**`DateTime`**](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html) +[**`DateTime`**](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html) type to represent a date and a time in a timezone. For more abstract moment-in-time tracking such as internal timekeeping @@ -104,15 +104,15 @@ is an opaque but monotonically-increasing representation of a moment in time. `DateTime` is timezone-aware and must be constructed from -the [**`TimeZone`**](https://docs.rs/chrono/0.4.6/chrono/offset/trait.TimeZone.html) object, +the [**`TimeZone`**](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html) object, which defines how the local date is converted to and back from the UTC date. There are three well-known `TimeZone` implementations: -* [**`Utc`**](https://docs.rs/chrono/0.4.6/chrono/offset/struct.Utc.html) specifies the UTC time zone. It is most efficient. +* [**`Utc`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html) specifies the UTC time zone. It is most efficient. -* [**`Local`**](https://docs.rs/chrono/0.4.6/chrono/offset/struct.Local.html) specifies the system local time zone. +* [**`Local`**](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html) specifies the system local time zone. -* [**`FixedOffset`**](https://docs.rs/chrono/0.4.6/chrono/offset/struct.FixedOffset.html) specifies +* [**`FixedOffset`**](https://docs.rs/chrono/0.4/chrono/offset/struct.FixedOffset.html) specifies an arbitrary, fixed time zone such as UTC+09:00 or UTC-10:30. This often results from the parsed textual date and time. Since it stores the most information and does not depend on the system environment, @@ -120,12 +120,12 @@ `DateTime`s with different `TimeZone` types are distinct and do not mix, but can be converted to each other using -the [`DateTime::with_timezone`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.with_timezone) method. +the [`DateTime::with_timezone`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.with_timezone) method. You can get the current date and time in the UTC time zone -([`Utc::now()`](https://docs.rs/chrono/0.4.6/chrono/offset/struct.Utc.html#method.now)) +([`Utc::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Utc.html#method.now)) or in the local time zone -([`Local::now()`](https://docs.rs/chrono/0.4.6/chrono/offset/struct.Local.html#method.now)). +([`Local::now()`](https://docs.rs/chrono/0.4/chrono/offset/struct.Local.html#method.now)). ```rust use chrono::prelude::*; @@ -166,17 +166,19 @@ ``` Various properties are available to the date and time, and can be altered individually. -Most of them are defined in the traits [`Datelike`](https://docs.rs/chrono/0.4.6/chrono/trait.Datelike.html) and -[`Timelike`](https://docs.rs/chrono/0.4.6/chrono/trait.Timelike.html) which you should `use` before. +Most of them are defined in the traits [`Datelike`](https://docs.rs/chrono/0.4/chrono/trait.Datelike.html) and +[`Timelike`](https://docs.rs/chrono/0.4/chrono/trait.Timelike.html) which you should `use` before. Addition and subtraction is also supported. The following illustrates most supported operations to the date and time: ```rust +extern crate time; + use chrono::prelude::*; use time::Duration; // assume this returned `2014-11-28T21:45:59.324310806+09:00`: -let dt = Local::now(); +let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806); // property accessors assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28)); @@ -210,15 +212,15 @@ ### Formatting and Parsing -Formatting is done via the [`format`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.format) method, +Formatting is done via the [`format`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.format) method, which format is equivalent to the familiar `strftime` format. -See [`format::strftime`](https://docs.rs/chrono/0.4.6/chrono/format/strftime/index.html#specifiers) +See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers) documentation for full syntax and list of specifiers. The default `to_string` method and `{:?}` specifier also give a reasonable representation. -Chrono also provides [`to_rfc2822`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.to_rfc2822) and -[`to_rfc3339`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.to_rfc3339) methods +Chrono also provides [`to_rfc2822`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.to_rfc2822) and +[`to_rfc3339`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.to_rfc3339) methods for well-known formats. ```rust @@ -248,23 +250,23 @@ ([`std::fmt::Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html)) format specifier prints, and requires the offset to be present. -2. [`DateTime::parse_from_str`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.parse_from_str) parses +2. [`DateTime::parse_from_str`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_str) parses a date and time with offsets and returns `DateTime`. This should be used when the offset is a part of input and the caller cannot guess that. It *cannot* be used when the offset can be missing. - [`DateTime::parse_from_rfc2822`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.parse_from_rfc2822) + [`DateTime::parse_from_rfc2822`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_rfc2822) and - [`DateTime::parse_from_rfc3339`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.parse_from_rfc3339) + [`DateTime::parse_from_rfc3339`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.parse_from_rfc3339) are similar but for well-known formats. -3. [`Offset::datetime_from_str`](https://docs.rs/chrono/0.4.6/chrono/offset/trait.TimeZone.html#method.datetime_from_str) is +3. [`Offset::datetime_from_str`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.datetime_from_str) is similar but returns `DateTime` of given offset. When the explicit offset is missing from the input, it simply uses given offset. It issues an error when the input contains an explicit offset different from the current offset. More detailed control over the parsing process is available via -[`format`](https://docs.rs/chrono/0.4.6/chrono/format/index.html) module. +[`format`](https://docs.rs/chrono/0.4/chrono/format/index.html) module. ```rust use chrono::prelude::*; @@ -296,23 +298,23 @@ assert!(Utc.datetime_from_str("Sat Nov 28 12:00:09 2014", "%a %b %e %T %Y").is_err()); ``` -Again : See [`format::strftime`](https://docs.rs/chrono/0.4.6/chrono/format/strftime/index.html#specifiers) +Again : See [`format::strftime`](https://docs.rs/chrono/0.4/chrono/format/strftime/index.html#specifiers) documentation for full syntax and list of specifiers. ### Conversion from and to EPOCH timestamps -Use [`Utc.timestamp(seconds, nanoseconds)`](https://docs.rs/chrono/0.4.6/chrono/offset/trait.TimeZone.html#method.timestamp) -to construct a [`DateTime`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html) from a UNIX timestamp +Use [`Utc.timestamp(seconds, nanoseconds)`](https://docs.rs/chrono/0.4/chrono/offset/trait.TimeZone.html#method.timestamp) +to construct a [`DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html) from a UNIX timestamp (seconds, nanoseconds that passed since January 1st 1970). -Use [`DateTime.timestamp`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.timestamp) to get the timestamp (in seconds) -from a [`DateTime`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html). Additionally, you can use -[`DateTime.timestamp_subsec_nanos`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.timestamp_subsec_nanos) +Use [`DateTime.timestamp`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp) to get the timestamp (in seconds) +from a [`DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html). Additionally, you can use +[`DateTime.timestamp_subsec_nanos`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.timestamp_subsec_nanos) to get the number of additional number of nanoseconds. ```rust // We need the trait in scope to use Utc::timestamp(). -use chrono::TimeZone; +use chrono::{DateTime, TimeZone, Utc}; // Construct a datetime from epoch: let dt = Utc.timestamp(1_500_000_000, 0); @@ -325,7 +327,7 @@ ### Individual date -Chrono also provides an individual date type ([**`Date`**](https://docs.rs/chrono/0.4.6/chrono/struct.Date.html)). +Chrono also provides an individual date type ([**`Date`**](https://docs.rs/chrono/0.4/chrono/struct.Date.html)). It also has time zones attached, and have to be constructed via time zones. Most operations available to `DateTime` are also available to `Date` whenever appropriate. @@ -344,26 +346,26 @@ There is no timezone-aware `Time` due to the lack of usefulness and also the complexity. -`DateTime` has [`date`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.date) method +`DateTime` has [`date`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.date) method which returns a `Date` which represents its date component. -There is also a [`time`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.time) method, +There is also a [`time`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.time) method, which simply returns a naive local time described below. ### Naive date and time Chrono provides naive counterparts to `Date`, (non-existent) `Time` and `DateTime` -as [**`NaiveDate`**](https://docs.rs/chrono/0.4.6/chrono/naive/struct.NaiveDate.html), -[**`NaiveTime`**](https://docs.rs/chrono/0.4.6/chrono/naive/struct.NaiveTime.html) and -[**`NaiveDateTime`**](https://docs.rs/chrono/0.4.6/chrono/naive/struct.NaiveDateTime.html) respectively. +as [**`NaiveDate`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html), +[**`NaiveTime`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveTime.html) and +[**`NaiveDateTime`**](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDateTime.html) respectively. They have almost equivalent interfaces as their timezone-aware twins, but are not associated to time zones obviously and can be quite low-level. They are mostly useful for building blocks for higher-level types. Timezone-aware `DateTime` and `Date` types have two methods returning naive versions: -[`naive_local`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.naive_local) returns +[`naive_local`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_local) returns a view to the naive local time, -and [`naive_utc`](https://docs.rs/chrono/0.4.6/chrono/struct.DateTime.html#method.naive_utc) returns +and [`naive_utc`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html#method.naive_utc) returns a view to the naive UTC time. ## Limitations @@ -375,7 +377,7 @@ Time types are limited in the nanosecond accuracy. [Leap seconds are supported in the representation but -Chrono doesn't try to make use of them](https://docs.rs/chrono/0.4.6/chrono/naive/struct.NaiveTime.html#leap-second-handling). +Chrono doesn't try to make use of them](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveTime.html#leap-second-handling). (The main reason is that leap seconds are not really predictable.) Almost *every* operation over the possible leap seconds will ignore them. Consider using `NaiveDateTime` with the implicit TAI (International Atomic Time) scale diff -Nru rust-chrono-0.4.6/src/datetime.rs rust-chrono-0.4.7/src/datetime.rs --- rust-chrono-0.4.6/src/datetime.rs 2018-07-28 21:09:27.000000000 +0000 +++ rust-chrono-0.4.7/src/datetime.rs 2019-04-08 16:44:30.000000000 +0000 @@ -235,6 +235,75 @@ } } +/// Convert a `DateTime` instance into a `DateTime` instance. +impl From> for DateTime { + /// Convert this `DateTime` instance into a `DateTime` instance. + /// + /// Conversion is done via [`DateTime::with_timezone`]. Note that the converted value returned by + /// this will be created with a fixed timezone offset of 0. + fn from(src: DateTime) -> Self { + src.with_timezone(&FixedOffset::east(0)) + } +} + +/// Convert a `DateTime` instance into a `DateTime` instance. +#[cfg(feature="clock")] +impl From> for DateTime { + /// Convert this `DateTime` instance into a `DateTime` instance. + /// + /// Conversion is performed via [`DateTime::with_timezone`], accounting for the difference in timezones. + fn from(src: DateTime) -> Self { + src.with_timezone(&Local) + } +} + +/// Convert a `DateTime` instance into a `DateTime` instance. +impl From> for DateTime { + /// Convert this `DateTime` instance into a `DateTime` instance. + /// + /// Conversion is performed via [`DateTime::with_timezone`], accounting for the timezone + /// difference. + fn from(src: DateTime) -> Self { + src.with_timezone(&Utc) + } +} + +/// Convert a `DateTime` instance into a `DateTime` instance. +#[cfg(feature="clock")] +impl From> for DateTime { + /// Convert this `DateTime` instance into a `DateTime` instance. + /// + /// Conversion is performed via [`DateTime::with_timezone`]. Returns the equivalent value in local + /// time. + fn from(src: DateTime) -> Self { + src.with_timezone(&Local) + } +} + +/// Convert a `DateTime` instance into a `DateTime` instance. +#[cfg(feature="clock")] +impl From> for DateTime { + /// Convert this `DateTime` instance into a `DateTime` instance. + /// + /// Conversion is performed via [`DateTime::with_timezone`], accounting for the difference in + /// timezones. + fn from(src: DateTime) -> Self { + src.with_timezone(&Utc) + } +} + +/// Convert a `DateTime` instance into a `DateTime` instance. +#[cfg(feature="clock")] +impl From> for DateTime { + /// Convert this `DateTime` instance into a `DateTime` instance. + /// + /// Conversion is performed via [`DateTime::with_timezone`]. Note that the converted value returned + /// by this will be created with a fixed timezone offset of 0. + fn from(src: DateTime) -> Self { + src.with_timezone(&FixedOffset::east(0)) + } +} + /// Maps the local datetime to other datetime with given conversion function. fn map_local(dt: &DateTime, mut f: F) -> Option> where F: FnMut(NaiveDateTime) -> Option { @@ -616,6 +685,14 @@ } } +#[test] +fn test_auto_conversion() { + let utc_dt = Utc.ymd(2018, 9, 5).and_hms(23, 58, 0); + let cdt_dt = FixedOffset::west(5 * 60 * 60).ymd(2018, 9, 5).and_hms(18, 58, 0); + let utc_dt2: DateTime = cdt_dt.into(); + assert_eq!(utc_dt, utc_dt2); +} + #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))] fn test_encodable_json(to_string_utc: FUtc, to_string_fixed: FFixed) where FUtc: Fn(&DateTime) -> Result, diff -Nru rust-chrono-0.4.6/src/format/parse.rs rust-chrono-0.4.7/src/format/parse.rs --- rust-chrono-0.4.6/src/format/parse.rs 2018-07-28 21:09:27.000000000 +0000 +++ rust-chrono-0.4.7/src/format/parse.rs 2019-04-07 21:57:07.000000000 +0000 @@ -4,6 +4,8 @@ //! Date and time parsing routines. +#![allow(deprecated)] + use std::usize; use Weekday; diff -Nru rust-chrono-0.4.6/src/format/scan.rs rust-chrono-0.4.7/src/format/scan.rs --- rust-chrono-0.4.6/src/format/scan.rs 2018-07-28 21:09:27.000000000 +0000 +++ rust-chrono-0.4.7/src/format/scan.rs 2019-04-07 21:57:07.000000000 +0000 @@ -5,6 +5,8 @@ * Various scanning routines for the parser. */ +#![allow(deprecated)] + use Weekday; use super::{ParseResult, TOO_SHORT, INVALID, OUT_OF_RANGE}; diff -Nru rust-chrono-0.4.6/src/lib.rs rust-chrono-0.4.7/src/lib.rs --- rust-chrono-0.4.6/src/lib.rs 2018-08-25 20:45:32.000000000 +0000 +++ rust-chrono-0.4.7/src/lib.rs 2019-06-21 20:56:57.000000000 +0000 @@ -66,7 +66,7 @@ //! months. //! //! Chrono does not yet natively support -//! the standard [`Duration`](https://docs.rs/time/0.1.40/time/struct.Duration.html) type, +//! the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type, //! but it will be supported in the future. //! Meanwhile you can convert between two types with //! [`Duration::from_std`](https://docs.rs/time/0.1.40/time/struct.Duration.html#method.from_std) @@ -158,15 +158,15 @@ //! The following illustrates most supported operations to the date and time: //! //! ```rust -//! # extern crate chrono; extern crate time; fn main() { +//! # extern crate chrono; +//! extern crate time; +//! +//! # fn main() { //! use chrono::prelude::*; //! use time::Duration; //! -//! # /* we intentionally fake the datetime... //! // assume this returned `2014-11-28T21:45:59.324310806+09:00`: -//! let dt = Local::now(); -//! # */ // up to here. we now define a fixed datetime for the illustrative purpose. -//! # let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806); +//! let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806); //! //! // property accessors //! assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28)); @@ -302,10 +302,8 @@ //! to get the number of additional number of nanoseconds. //! //! ```rust -//! # use chrono::DateTime; -//! # use chrono::Utc; //! // We need the trait in scope to use Utc::timestamp(). -//! use chrono::TimeZone; +//! use chrono::{DateTime, TimeZone, Utc}; //! //! // Construct a datetime from epoch: //! let dt = Utc.timestamp(1_500_000_000, 0); @@ -413,6 +411,12 @@ extern crate rustc_serialize; #[cfg(feature = "serde")] extern crate serde as serdelib; +#[cfg(test)] +#[macro_use] +extern crate doc_comment; + +#[cfg(test)] +doctest!("../README.md"); // this reexport is to aid the transition and should not be in the prelude! pub use oldtime::Duration; @@ -451,7 +455,7 @@ mod oldtime; pub mod offset; pub mod naive { - //! Date and time types which do not concern about the timezones. + //! Date and time types unconcerned with timezones. //! //! They are primarily building blocks for other types //! (e.g. [`TimeZone`](../offset/trait.TimeZone.html)), diff -Nru rust-chrono-0.4.6/src/naive/datetime.rs rust-chrono-0.4.7/src/naive/datetime.rs --- rust-chrono-0.4.6/src/naive/datetime.rs 2018-07-28 21:09:40.000000000 +0000 +++ rust-chrono-0.4.7/src/naive/datetime.rs 2019-04-07 21:57:07.000000000 +0000 @@ -305,21 +305,33 @@ /// Note that this does *not* account for the timezone! /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch. /// + /// # Panics + /// /// Note also that this does reduce the number of years that can be - /// represented from ~584 Billion to ~584. (If this is a problem, - /// please file an issue to let me know what domain needs nanosecond - /// precision over millenia, I'm curious.) + /// represented from ~584 Billion to ~584 years. The dates that can be + /// represented as nanoseconds are between 1677-09-21T00:12:44.0 and + /// 2262-04-11T23:47:16.854775804. + /// + /// (If this is a problem, please file an issue to let me know what domain + /// needs nanosecond precision over millenia, I'm curious.) /// /// # Example /// /// ~~~~ - /// use chrono::NaiveDate; + /// use chrono::{NaiveDate, NaiveDateTime}; /// /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_nano(0, 0, 1, 444); /// assert_eq!(dt.timestamp_nanos(), 1_000_000_444); /// /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms_nano(1, 46, 40, 555); - /// assert_eq!(dt.timestamp_nanos(), 1_000_000_000_000_000_555); + /// + /// const A_BILLION: i64 = 1_000_000_000; + /// let nanos = dt.timestamp_nanos(); + /// assert_eq!(nanos, 1_000_000_000_000_000_555); + /// assert_eq!( + /// dt, + /// NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32) + /// ); /// ~~~~ #[inline] pub fn timestamp_nanos(&self) -> i64 { @@ -2348,4 +2360,24 @@ let time = base + Duration::microseconds(t); assert_eq!(t, time.signed_duration_since(base).num_microseconds().unwrap()); } + + #[test] + fn test_nanosecond_range() { + const A_BILLION: i64 = 1_000_000_000; + let maximum = "2262-04-11T23:47:16.854775804"; + let parsed: NaiveDateTime = maximum.parse().unwrap(); + let nanos = parsed.timestamp_nanos(); + assert_eq!( + parsed, + NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32) + ); + + let minimum = "1677-09-21T00:12:44.000000000"; + let parsed: NaiveDateTime = minimum.parse().unwrap(); + let nanos = parsed.timestamp_nanos(); + assert_eq!( + parsed, + NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32) + ); + } } diff -Nru rust-chrono-0.4.6/src/offset/fixed.rs rust-chrono-0.4.7/src/offset/fixed.rs --- rust-chrono-0.4.6/src/offset/fixed.rs 2018-07-28 21:09:27.000000000 +0000 +++ rust-chrono-0.4.7/src/offset/fixed.rs 2019-06-21 20:56:57.000000000 +0000 @@ -86,11 +86,13 @@ } /// Returns the number of seconds to add to convert from UTC to the local time. + #[inline] pub fn local_minus_utc(&self) -> i32 { self.local_minus_utc } /// Returns the number of seconds to add to convert from the local time to UTC. + #[inline] pub fn utc_minus_local(&self) -> i32 { -self.local_minus_utc } diff -Nru rust-chrono-0.4.6/src/offset/mod.rs rust-chrono-0.4.7/src/offset/mod.rs --- rust-chrono-0.4.6/src/offset/mod.rs 2018-07-28 21:09:40.000000000 +0000 +++ rust-chrono-0.4.7/src/offset/mod.rs 2019-06-21 20:56:57.000000000 +0000 @@ -20,13 +20,13 @@ use std::fmt; +use format::{parse, ParseResult, Parsed, StrftimeItems}; +use naive::{NaiveDate, NaiveDateTime, NaiveTime}; use Weekday; -use naive::{NaiveDate, NaiveTime, NaiveDateTime}; use {Date, DateTime}; -use format::{parse, Parsed, ParseResult, StrftimeItems}; /// The conversion result from the local time to the timezone-aware datetime types. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug, Copy, Eq, Hash)] pub enum LocalResult { /// Given local time representation is invalid. /// This can occur when, for example, the positive timezone transition. @@ -41,17 +41,26 @@ impl LocalResult { /// Returns `Some` only when the conversion result is unique, or `None` otherwise. pub fn single(self) -> Option { - match self { LocalResult::Single(t) => Some(t), _ => None } + match self { + LocalResult::Single(t) => Some(t), + _ => None, + } } /// Returns `Some` for the earliest possible conversion result, or `None` if none. pub fn earliest(self) -> Option { - match self { LocalResult::Single(t) | LocalResult::Ambiguous(t,_) => Some(t), _ => None } + match self { + LocalResult::Single(t) | LocalResult::Ambiguous(t, _) => Some(t), + _ => None, + } } /// Returns `Some` for the latest possible conversion result, or `None` if none. pub fn latest(self) -> Option { - match self { LocalResult::Single(t) | LocalResult::Ambiguous(_,t) => Some(t), _ => None } + match self { + LocalResult::Single(t) | LocalResult::Ambiguous(_, t) => Some(t), + _ => None, + } } /// Maps a `LocalResult` into `LocalResult` with given function. @@ -72,8 +81,9 @@ #[inline] pub fn and_time(self, time: NaiveTime) -> LocalResult> { match self { - LocalResult::Single(d) => d.and_time(time) - .map_or(LocalResult::None, LocalResult::Single), + LocalResult::Single(d) => d + .and_time(time) + .map_or(LocalResult::None, LocalResult::Single), _ => LocalResult::None, } } @@ -85,8 +95,9 @@ #[inline] pub fn and_hms_opt(self, hour: u32, min: u32, sec: u32) -> LocalResult> { match self { - LocalResult::Single(d) => d.and_hms_opt(hour, min, sec) - .map_or(LocalResult::None, LocalResult::Single), + LocalResult::Single(d) => d + .and_hms_opt(hour, min, sec) + .map_or(LocalResult::None, LocalResult::Single), _ => LocalResult::None, } } @@ -97,11 +108,17 @@ /// /// Propagates any error. Ambiguous result would be discarded. #[inline] - pub fn and_hms_milli_opt(self, hour: u32, min: u32, sec: u32, - milli: u32) -> LocalResult> { + pub fn and_hms_milli_opt( + self, + hour: u32, + min: u32, + sec: u32, + milli: u32, + ) -> LocalResult> { match self { - LocalResult::Single(d) => d.and_hms_milli_opt(hour, min, sec, milli) - .map_or(LocalResult::None, LocalResult::Single), + LocalResult::Single(d) => d + .and_hms_milli_opt(hour, min, sec, milli) + .map_or(LocalResult::None, LocalResult::Single), _ => LocalResult::None, } } @@ -112,11 +129,17 @@ /// /// Propagates any error. Ambiguous result would be discarded. #[inline] - pub fn and_hms_micro_opt(self, hour: u32, min: u32, sec: u32, - micro: u32) -> LocalResult> { + pub fn and_hms_micro_opt( + self, + hour: u32, + min: u32, + sec: u32, + micro: u32, + ) -> LocalResult> { match self { - LocalResult::Single(d) => d.and_hms_micro_opt(hour, min, sec, micro) - .map_or(LocalResult::None, LocalResult::Single), + LocalResult::Single(d) => d + .and_hms_micro_opt(hour, min, sec, micro) + .map_or(LocalResult::None, LocalResult::Single), _ => LocalResult::None, } } @@ -127,15 +150,20 @@ /// /// Propagates any error. Ambiguous result would be discarded. #[inline] - pub fn and_hms_nano_opt(self, hour: u32, min: u32, sec: u32, - nano: u32) -> LocalResult> { + pub fn and_hms_nano_opt( + self, + hour: u32, + min: u32, + sec: u32, + nano: u32, + ) -> LocalResult> { match self { - LocalResult::Single(d) => d.and_hms_nano_opt(hour, min, sec, nano) - .map_or(LocalResult::None, LocalResult::Single), + LocalResult::Single(d) => d + .and_hms_nano_opt(hour, min, sec, nano) + .map_or(LocalResult::None, LocalResult::Single), _ => LocalResult::None, } } - } impl LocalResult { @@ -144,7 +172,7 @@ match self { LocalResult::None => panic!("No such local time"), LocalResult::Single(t) => t, - LocalResult::Ambiguous(t1,t2) => { + LocalResult::Ambiguous(t1, t2) => { panic!("Ambiguous local time, ranging from {:?} to {:?}", t1, t2) } } @@ -345,10 +373,36 @@ /// }; /// ~~~~ fn timestamp_millis_opt(&self, millis: i64) -> LocalResult> { - let (secs, millis) = (millis / 1000, millis % 1000); + let (mut secs, mut millis) = (millis / 1000, millis % 1000); + if millis < 0 { + secs -= 1; + millis += 1000; + } self.timestamp_opt(secs, millis as u32 * 1_000_000) } + /// Makes a new `DateTime` from the number of non-leap nanoseconds + /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp"). + /// + /// Unlike [`timestamp_millis`](#method.timestamp_millis), this never + /// panics. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{Utc, TimeZone}; + /// + /// assert_eq!(Utc.timestamp_nanos(1431648000000000).timestamp(), 1431648); + /// ~~~~ + fn timestamp_nanos(&self, nanos: i64) -> DateTime { + let (mut secs, mut nanos) = (nanos / 1_000_000_000, nanos % 1_000_000_000); + if nanos < 0 { + secs -= 1; + nanos += 1_000_000_000; + } + self.timestamp_opt(secs, nanos as u32).unwrap() + } + /// Parses a string with the specified format string and /// returns a `DateTime` with the current offset. /// See the [`format::strftime` module](../format/strftime/index.html) @@ -384,9 +438,8 @@ /// Converts the local `NaiveDateTime` to the timezone-aware `DateTime` if possible. fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult> { - self.offset_from_local_datetime(local).map(|offset| { - DateTime::from_utc(*local - offset.fix(), offset) - }) + self.offset_from_local_datetime(local) + .map(|offset| DateTime::from_utc(*local - offset.fix(), offset)) } /// Creates the offset for given UTC `NaiveDate`. This cannot fail. @@ -408,12 +461,52 @@ } } -mod utc; mod fixed; -#[cfg(feature="clock")] +#[cfg(feature = "clock")] mod local; +mod utc; -pub use self::utc::Utc; pub use self::fixed::FixedOffset; -#[cfg(feature="clock")] +#[cfg(feature = "clock")] pub use self::local::Local; +pub use self::utc::Utc; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_negative_millis() { + let dt = Utc.timestamp_millis(-1000); + assert_eq!(dt.to_string(), "1969-12-31 23:59:59 UTC"); + let dt = Utc.timestamp_millis(-999); + assert_eq!(dt.to_string(), "1969-12-31 23:59:59.001 UTC"); + let dt = Utc.timestamp_millis(-1); + assert_eq!(dt.to_string(), "1969-12-31 23:59:59.999 UTC"); + let dt = Utc.timestamp_millis(-60000); + assert_eq!(dt.to_string(), "1969-12-31 23:59:00 UTC"); + let dt = Utc.timestamp_millis(-3600000); + assert_eq!(dt.to_string(), "1969-12-31 23:00:00 UTC"); + } + + #[test] + fn test_negative_nanos() { + let dt = Utc.timestamp_nanos(-1_000_000_000); + assert_eq!(dt.to_string(), "1969-12-31 23:59:59 UTC"); + let dt = Utc.timestamp_nanos(-999_999_999); + assert_eq!(dt.to_string(), "1969-12-31 23:59:59.000000001 UTC"); + let dt = Utc.timestamp_nanos(-1); + assert_eq!(dt.to_string(), "1969-12-31 23:59:59.999999999 UTC"); + let dt = Utc.timestamp_nanos(-60_000_000_000); + assert_eq!(dt.to_string(), "1969-12-31 23:59:00 UTC"); + let dt = Utc.timestamp_nanos(-3_600_000_000_000); + assert_eq!(dt.to_string(), "1969-12-31 23:00:00 UTC"); + } + + #[test] + fn test_nanos_never_panics() { + Utc.timestamp_nanos(i64::max_value()); + Utc.timestamp_nanos(i64::default()); + Utc.timestamp_nanos(i64::min_value()); + } +} diff -Nru rust-chrono-0.4.6/.travis.yml rust-chrono-0.4.7/.travis.yml --- rust-chrono-0.4.6/.travis.yml 2018-08-25 20:45:32.000000000 +0000 +++ rust-chrono-0.4.7/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -language: rust -sudo: false -rust: - # 1.13.0 is the earliest version that Serde 1.0 tests, so we follow suit - - 1.13.0 - - stable - - beta - - nightly -os: - - linux - - osx -matrix: - allow_failures: - - rust: nightly - env: CLIPPY=n - include: - - rust: nightly - env: CLIPPY=y - -env: - global: - - LD_LIBRARY_PATH: /usr/local/lib - - CLIPPY: n -script: ./ci/travis.sh -notifications: - email: false - irc: - channels: - - "irc.mozilla.org#chronotope" - template: - - "%{repository_slug}/%{branch} (%{commit} - %{author}): %{message}" - skip_join: true