diff --git a/src/datetime.rs b/src/datetime.rs index 5551352..3d54146 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -51,10 +51,18 @@ impl DateTime { Time::from_utc(self.datetime.time().clone(), self.offset.clone()) } - /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC. + /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC + /// (aka "UNIX timestamp"). #[inline] + pub fn timestamp(&self) -> i64 { + self.datetime.timestamp() + } + + /// Same to `DateTime::timestamp`. + #[inline] + #[deprecated = "Use `DateTime::timestamp` instead."] pub fn num_seconds_from_unix_epoch(&self) -> i64 { - self.datetime.num_seconds_from_unix_epoch() + self.timestamp() } /// Retrieves an associated offset from UTC. diff --git a/src/format/mod.rs b/src/format/mod.rs index 9605474..0634878 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -285,7 +285,7 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt t.nanosecond() / 1_000_000_000) as i64)), Nanosecond => (9, time.map(|t| (t.nanosecond() % 1_000_000_000) as i64)), Timestamp => (1, match (date, time) { - (Some(d), Some(t)) => Some(d.and_time(*t).num_seconds_from_unix_epoch()), + (Some(d), Some(t)) => Some(d.and_time(*t).timestamp()), (_, _) => None }), }; diff --git a/src/format/parsed.rs b/src/format/parsed.rs index 840973f..00993ca 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -456,8 +456,8 @@ impl Parsed { let datetime = date.and_time(time); // verify the timestamp field if any - // the following is safe, `num_seconds_from_unix_epoch` is very limited in range - let timestamp = datetime.num_seconds_from_unix_epoch() - offset as i64; + // the following is safe, `timestamp` is very limited in range + let timestamp = datetime.timestamp() - offset as i64; if let Some(given_timestamp) = self.timestamp { // if `datetime` represents a leap second, it might be off by one second. if given_timestamp != timestamp && @@ -478,7 +478,7 @@ impl Parsed { // reconstruct date and time fields from timestamp let ts = try!(timestamp.checked_add(offset as i64).ok_or(OUT_OF_RANGE)); - let datetime = NaiveDateTime::from_num_seconds_from_unix_epoch_opt(ts, 0); + let datetime = NaiveDateTime::from_timestamp_opt(ts, 0); let mut datetime = try!(datetime.ok_or(OUT_OF_RANGE)); // fill year, ordinal, hour, minute and second fields from timestamp. @@ -551,7 +551,7 @@ impl Parsed { // make a naive `DateTime` from given timestamp and (if any) nanosecond. // an empty `nanosecond` is always equal to zero, so missing nanosecond is fine. let nanosecond = self.nanosecond.unwrap_or(0); - let dt = NaiveDateTime::from_num_seconds_from_unix_epoch_opt(timestamp, nanosecond); + let dt = NaiveDateTime::from_timestamp_opt(timestamp, nanosecond); let dt = try!(dt.ok_or(OUT_OF_RANGE)); // we cannot handle offsets larger than i32 at all. give up if so. diff --git a/src/naive/datetime.rs b/src/naive/datetime.rs index 5374256..6b372c9 100644 --- a/src/naive/datetime.rs +++ b/src/naive/datetime.rs @@ -34,23 +34,23 @@ impl NaiveDateTime { } /// Makes a new `NaiveDateTime` from the number of non-leap seconds - /// since January 1, 1970 0:00:00 UTC and the number of nanoseconds - /// since the last whole non-leap second. + /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") + /// and the number of nanoseconds since the last whole non-leap second. /// /// Fails on the out-of-range number of seconds and/or invalid nanosecond. #[inline] - pub fn from_num_seconds_from_unix_epoch(secs: i64, nsecs: u32) -> NaiveDateTime { - let datetime = NaiveDateTime::from_num_seconds_from_unix_epoch_opt(secs, nsecs); + pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime { + let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs); datetime.expect("invalid or out-of-range datetime") } /// Makes a new `NaiveDateTime` from the number of non-leap seconds - /// since January 1, 1970 0:00:00 UTC and the number of nanoseconds - /// since the last whole non-leap second. + /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") + /// and the number of nanoseconds since the last whole non-leap second. /// /// Returns `None` on the out-of-range number of seconds and/or invalid nanosecond. #[inline] - pub fn from_num_seconds_from_unix_epoch_opt(secs: i64, nsecs: u32) -> Option { + pub fn from_timestamp_opt(secs: i64, nsecs: u32) -> Option { let (days, secs) = div_mod_floor(secs, 86400); let date = days.to_i32().and_then(|days| days.checked_add(719163)) .and_then(|days_ce| NaiveDate::from_num_days_from_ce_opt(days_ce)); @@ -61,6 +61,20 @@ impl NaiveDateTime { } } + /// Same to `NaiveDateTime::from_timestamp`. + #[inline] + #[deprecated = "Use `NaiveDateTime::from_timestamp` instead."] + pub fn from_num_seconds_from_unix_epoch(secs: i64, nsecs: u32) -> NaiveDateTime { + NaiveDateTime::from_timestamp(secs, nsecs) + } + + /// Same to `NaiveDateTime::from_timestamp_opt`. + #[inline] + #[deprecated = "Use `NaiveDateTime::from_timestamp` instead."] + pub fn from_num_seconds_from_unix_epoch_opt(secs: i64, nsecs: u32) -> Option { + NaiveDateTime::from_timestamp_opt(secs, nsecs) + } + /// Parses a string with the specified format string and returns a new `NaiveDateTime`. /// See the `format::strftime` module on the supported escape sequences. pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { @@ -81,15 +95,23 @@ impl NaiveDateTime { self.time } - /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC. + /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC + /// (aka "UNIX timestamp"). /// Note that this does *not* account for the timezone! #[inline] - pub fn num_seconds_from_unix_epoch(&self) -> i64 { + pub fn timestamp(&self) -> i64 { let ndays = self.date.num_days_from_ce() as i64; let nseconds = self.time.num_seconds_from_midnight() as i64; (ndays - 719163) * 86400 + nseconds } + /// Same to `NaiveDateTime::timestamp`. + #[inline] + #[deprecated = "Use `NaiveDateTime::timestamp` instead."] + pub fn num_seconds_from_unix_epoch(&self) -> i64 { + self.timestamp() + } + /// Adds given `Duration` to the current date and time. /// /// Returns `None` when it will result in overflow. @@ -300,9 +322,9 @@ mod tests { use std::i64; #[test] - fn test_datetime_from_num_seconds_from_unix_epoch() { - let from_timestamp = |&: secs| NaiveDateTime::from_num_seconds_from_unix_epoch_opt(secs, 0); - let ymdhms = |&: y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s); + fn test_datetime_from_timestamp() { + let from_timestamp = |secs| NaiveDateTime::from_timestamp_opt(secs, 0); + let ymdhms = |y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s); assert_eq!(from_timestamp(-1), Some(ymdhms(1969, 12, 31, 23, 59, 59))); assert_eq!(from_timestamp(0), Some(ymdhms(1970, 1, 1, 0, 0, 0))); assert_eq!(from_timestamp(1), Some(ymdhms(1970, 1, 1, 0, 0, 1))); @@ -360,9 +382,8 @@ mod tests { } #[test] - fn test_datetime_num_seconds_from_unix_epoch() { - let to_timestamp = |&: y,m,d,h,n,s| - NaiveDate::from_ymd(y,m,d).and_hms(h,n,s).num_seconds_from_unix_epoch(); + fn test_datetime_timestamp() { + let to_timestamp = |y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s).timestamp(); assert_eq!(to_timestamp(1969, 12, 31, 23, 59, 59), -1); assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 0), 0); assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 1), 1); diff --git a/src/offset/mod.rs b/src/offset/mod.rs index 0e20768..7ab17b7 100644 --- a/src/offset/mod.rs +++ b/src/offset/mod.rs @@ -321,6 +321,27 @@ pub trait TimeZone: Sized { } } + /// Makes a new `DateTime` from the number of non-leap seconds + /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") + /// and the number of nanoseconds since the last whole non-leap second. + /// + /// Fails on the out-of-range number of seconds and/or invalid nanosecond. + fn timestamp(&self, secs: i64, nsecs: u32) -> DateTime { + self.timestamp_opt(secs, nsecs).unwrap() + } + + /// Makes a new `DateTime` from the number of non-leap seconds + /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") + /// and the number of nanoseconds since the last whole non-leap second. + /// + /// Returns `None` on the out-of-range number of seconds and/or invalid nanosecond. + fn timestamp_opt(&self, secs: i64, nsecs: u32) -> LocalResult> { + match NaiveDateTime::from_timestamp_opt(secs, nsecs) { + Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)), + None => LocalResult::None, + } + } + /// Parses a string with the specified format string and /// returns a `DateTime` with the current offset. /// See the `format::strftime` module on the supported escape sequences. diff --git a/src/offset/utc.rs b/src/offset/utc.rs index e741202..a61b1a3 100644 --- a/src/offset/utc.rs +++ b/src/offset/utc.rs @@ -29,7 +29,7 @@ impl UTC { /// Returns a `DateTime` which corresponds to the current date. pub fn now() -> DateTime { let spec = stdtime::get_time(); - let naive = NaiveDateTime::from_num_seconds_from_unix_epoch(spec.sec, spec.nsec as u32); + let naive = NaiveDateTime::from_timestamp(spec.sec, spec.nsec as u32); DateTime::from_utc(naive, UTC) } }