0.2.3: Fixed a couple of outstanding bugs.
- `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.
This commit is contained in:
parent
ffa86603ae
commit
2dbc11dcb1
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -8,6 +8,17 @@ Chrono obeys the principle of [Semantic Versioning](http://semver.org/).
|
||||||
There were/are numerous minor versions before 1.0 due to the language changes.
|
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 mechnical changes will be omitted from the following list.
|
||||||
|
|
||||||
|
## 0.2.3 (2015-02-27)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `DateTime<Tz>` and `Date<Tz>` is now `Copy`/`Send` when `Tz::Offset` is `Copy`/`Send`.
|
||||||
|
The implementations for them were mistakenly omitted. (#25)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `Local::from_utc_datetime` didn't set a correct offset. (#26)
|
||||||
|
|
||||||
## 0.2.1 (2015-02-21)
|
## 0.2.1 (2015-02-21)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
authors = ["Kang Seonghoon <public+rust@mearie.org>"]
|
authors = ["Kang Seonghoon <public+rust@mearie.org>"]
|
||||||
|
|
||||||
description = "Date and time library for Rust"
|
description = "Date and time library for Rust"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[Chrono][doc] 0.2.2
|
[Chrono][doc] 0.2.3
|
||||||
===================
|
===================
|
||||||
|
|
||||||
[![Chrono on Travis CI][travis-image]][travis]
|
[![Chrono on Travis CI][travis-image]][travis]
|
||||||
|
|
|
@ -284,6 +284,10 @@ impl<Tz: TimeZone> Datelike for Date<Tz> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need them as automatic impls cannot handle associated types
|
||||||
|
impl<Tz: TimeZone> Copy for Date<Tz> where <Tz as TimeZone>::Offset: Copy {}
|
||||||
|
unsafe impl<Tz: TimeZone> Send for Date<Tz> where <Tz as TimeZone>::Offset: Send {}
|
||||||
|
|
||||||
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Date<Tz2>> for Date<Tz> {
|
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Date<Tz2>> for Date<Tz> {
|
||||||
fn eq(&self, other: &Date<Tz2>) -> bool { self.date == other.date }
|
fn eq(&self, other: &Date<Tz2>) -> bool { self.date == other.date }
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,6 +259,10 @@ impl<Tz: TimeZone> Timelike for DateTime<Tz> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need them as automatic impls cannot handle associated types
|
||||||
|
impl<Tz: TimeZone> Copy for DateTime<Tz> where <Tz as TimeZone>::Offset: Copy {}
|
||||||
|
unsafe impl<Tz: TimeZone> Send for DateTime<Tz> where <Tz as TimeZone>::Offset: Send {}
|
||||||
|
|
||||||
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<DateTime<Tz2>> for DateTime<Tz> {
|
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<DateTime<Tz2>> for DateTime<Tz> {
|
||||||
fn eq(&self, other: &DateTime<Tz2>) -> bool { self.datetime == other.datetime }
|
fn eq(&self, other: &DateTime<Tz2>) -> bool { self.datetime == other.datetime }
|
||||||
}
|
}
|
||||||
|
@ -403,6 +407,14 @@ mod tests {
|
||||||
NaiveTime::from_hms(7, 8, 9));
|
NaiveTime::from_hms(7, 8, 9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_datetime_with_timezone() {
|
||||||
|
let local_now = Local::now();
|
||||||
|
let utc_now = local_now.with_timezone(&UTC);
|
||||||
|
let local_now2 = utc_now.with_timezone(&Local);
|
||||||
|
assert_eq!(local_now, local_now2);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn test_datetime_rfc2822_and_rfc3339() {
|
fn test_datetime_rfc2822_and_rfc3339() {
|
||||||
|
@ -466,5 +478,25 @@ mod tests {
|
||||||
let dt = Local::now().with_month(5).unwrap();
|
let dt = Local::now().with_month(5).unwrap();
|
||||||
assert_eq!(dt.format("%Y").to_string(), dt.with_timezone(&UTC).format("%Y").to_string());
|
assert_eq!(dt.format("%Y").to_string(), dt.with_timezone(&UTC).format("%Y").to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore] // XXX Rust issue #22818
|
||||||
|
fn test_datetime_is_copy() {
|
||||||
|
// UTC is known to be `Copy`.
|
||||||
|
let a = UTC::now();
|
||||||
|
let b = a;
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_datetime_is_send() {
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
// UTC is known to be `Send`.
|
||||||
|
let a = UTC::now();
|
||||||
|
thread::scoped(move || {
|
||||||
|
let _ = a;
|
||||||
|
}).join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
# Chrono 0.2.2
|
# Chrono 0.2.3
|
||||||
|
|
||||||
Date and time handling for Rust. (also known as `rust-chrono`)
|
Date and time handling for Rust. (also known as `rust-chrono`)
|
||||||
It aims to be a feature-complete superset of the [time](https://github.com/rust-lang/time) library.
|
It aims to be a feature-complete superset of the [time](https://github.com/rust-lang/time) library.
|
||||||
|
|
|
@ -35,7 +35,12 @@ fn tm_to_datetime(mut tm: stdtime::Tm) -> DateTime<Local> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a local `NaiveDateTime` to the `time::Timespec`.
|
/// Converts a local `NaiveDateTime` to the `time::Timespec`.
|
||||||
fn datetime_to_timespec(d: &NaiveDateTime) -> stdtime::Timespec {
|
fn datetime_to_timespec(d: &NaiveDateTime, local: bool) -> stdtime::Timespec {
|
||||||
|
// well, this exploits an undocumented `Tm::to_timespec` behavior
|
||||||
|
// to get the exact function we want (either `timegm` or `mktime`).
|
||||||
|
// the number 1 is arbitrary but should be non-zero to trigger `mktime`.
|
||||||
|
let tm_utcoff = if local {1} else {0};
|
||||||
|
|
||||||
let tm = stdtime::Tm {
|
let tm = stdtime::Tm {
|
||||||
tm_sec: d.second() as i32,
|
tm_sec: d.second() as i32,
|
||||||
tm_min: d.minute() as i32,
|
tm_min: d.minute() as i32,
|
||||||
|
@ -46,8 +51,7 @@ fn datetime_to_timespec(d: &NaiveDateTime) -> stdtime::Timespec {
|
||||||
tm_wday: 0, // to_local ignores this
|
tm_wday: 0, // to_local ignores this
|
||||||
tm_yday: 0, // and this
|
tm_yday: 0, // and this
|
||||||
tm_isdst: -1,
|
tm_isdst: -1,
|
||||||
tm_utcoff: 1, // this is arbitrary but should be nonzero
|
tm_utcoff: tm_utcoff,
|
||||||
// in order to make `to_timespec` use `rust_mktime` internally.
|
|
||||||
tm_nsec: d.nanosecond() as i32,
|
tm_nsec: d.nanosecond() as i32,
|
||||||
};
|
};
|
||||||
tm.to_timespec()
|
tm.to_timespec()
|
||||||
|
@ -94,7 +98,7 @@ impl TimeZone for Local {
|
||||||
self.from_local_datetime(&local.and_hms(0, 0, 0)).map(|datetime| datetime.date())
|
self.from_local_datetime(&local.and_hms(0, 0, 0)).map(|datetime| datetime.date())
|
||||||
}
|
}
|
||||||
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
|
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
|
||||||
let timespec = datetime_to_timespec(local);
|
let timespec = datetime_to_timespec(local, true);
|
||||||
LocalResult::Single(tm_to_datetime(stdtime::at(timespec)))
|
LocalResult::Single(tm_to_datetime(stdtime::at(timespec)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +106,8 @@ impl TimeZone for Local {
|
||||||
self.from_utc_datetime(&utc.and_hms(0, 0, 0)).date()
|
self.from_utc_datetime(&utc.and_hms(0, 0, 0)).date()
|
||||||
}
|
}
|
||||||
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
|
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
|
||||||
let timespec = datetime_to_timespec(utc);
|
let timespec = datetime_to_timespec(utc, false);
|
||||||
tm_to_datetime(stdtime::at_utc(timespec))
|
tm_to_datetime(stdtime::at(timespec))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue