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:
Kang Seonghoon 2015-02-27 13:08:20 +09:00
parent ffa86603ae
commit 2dbc11dcb1
7 changed files with 60 additions and 9 deletions

View File

@ -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

View File

@ -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"

View File

@ -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]

View File

@ -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 }
} }

View File

@ -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();
}
} }

View File

@ -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.

View File

@ -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))
} }
} }