diff --git a/src/offset_date_time.rs b/src/offset_date_time.rs index caa573937..56888f20c 100644 --- a/src/offset_date_time.rs +++ b/src/offset_date_time.rs @@ -74,7 +74,9 @@ impl OffsetDateTime { /// /// ```rust /// # use time::OffsetDateTime; + /// # if false { /// assert!(OffsetDateTime::now_local().is_ok()); + /// # } /// ``` #[cfg(feature = "local-offset")] #[cfg_attr(__time_03_docs, doc(cfg(feature = "local-offset")))] diff --git a/src/utc_offset.rs b/src/utc_offset.rs index b51fb10fc..9c17139b2 100644 --- a/src/utc_offset.rs +++ b/src/utc_offset.rs @@ -253,7 +253,9 @@ impl UtcOffset { /// # use time::{UtcOffset, OffsetDateTime}; /// let unix_epoch = OffsetDateTime::unix_epoch(); /// let local_offset = UtcOffset::local_offset_at(unix_epoch); + /// # if false { /// assert!(local_offset.is_ok()); + /// # } /// ``` #[cfg(feature = "local-offset")] #[cfg_attr(__time_03_docs, doc(cfg(feature = "local-offset")))] @@ -267,7 +269,9 @@ impl UtcOffset { /// ```rust /// # use time::UtcOffset; /// let local_offset = UtcOffset::current_local_offset(); + /// # if false { /// assert!(local_offset.is_ok()); + /// # } /// ``` #[cfg(feature = "local-offset")] #[cfg_attr(__time_03_docs, doc(cfg(feature = "local-offset")))] @@ -337,92 +341,96 @@ impl Display for UtcOffset { /// Attempt to obtain the system's UTC offset. If the offset cannot be /// determined, `None` is returned. #[cfg(feature = "local-offset")] -#[allow(clippy::too_many_lines)] +#[allow(clippy::too_many_lines, clippy::missing_const_for_fn)] fn local_offset_at(datetime: OffsetDateTime) -> Option { #[cfg(target_family = "unix")] { - use core::{convert::TryInto, mem::MaybeUninit}; - - /// Convert the given Unix timestamp to a `libc::tm`. Returns `None` on - /// any error. - fn timestamp_to_tm(timestamp: i64) -> Option { - extern "C" { - #[cfg_attr(target_os = "netbsd", link_name = "__tzset50")] - fn tzset(); - } - - // The exact type of `timestamp` beforehand can vary, so this - // conversion is necessary. - #[allow(clippy::useless_conversion)] - let timestamp = timestamp.try_into().ok()?; - - let mut tm = MaybeUninit::uninit(); - - // Update timezone information from system. `localtime_r` does not - // do this for us. - // - // Safety: tzset is thread-safe. - #[allow(unsafe_code)] - unsafe { - tzset(); - } - - // Safety: We are calling a system API, which mutates the `tm` - // variable. If a null pointer is returned, an error occurred. - #[allow(unsafe_code)] - let tm_ptr = unsafe { libc::localtime_r(×tamp, tm.as_mut_ptr()) }; - - if tm_ptr.is_null() { - None - } else { - // Safety: The value was initialized, as we no longer have a - // null pointer. - #[allow(unsafe_code)] - { - Some(unsafe { tm.assume_init() }) - } - } - } - - let tm = timestamp_to_tm(datetime.unix_timestamp())?; - - // `tm_gmtoff` extension - #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] - { - UtcOffset::seconds(tm.tm_gmtoff.try_into().ok()?).ok() - } - - // No `tm_gmtoff` extension - #[cfg(any(target_os = "solaris", target_os = "illumos"))] - { - use crate::Date; - use core::convert::TryFrom; - - let mut tm = tm; - if tm.tm_sec == 60 { - // Leap seconds are not currently supported. - tm.tm_sec = 59; - } + // See #293 for details. + let _ = datetime; + None - let local_timestamp = - Date::from_yo(1900 + tm.tm_year, u16::try_from(tm.tm_yday).ok()? + 1) - .ok()? - .with_hms( - tm.tm_hour.try_into().ok()?, - tm.tm_min.try_into().ok()?, - tm.tm_sec.try_into().ok()?, - ) - .ok()? - .assume_utc() - .unix_timestamp(); - - UtcOffset::seconds( - (local_timestamp - datetime.unix_timestamp()) - .try_into() - .ok()?, - ) - .ok() - } + // use core::{convert::TryInto, mem::MaybeUninit}; + // + // /// Convert the given Unix timestamp to a `libc::tm`. Returns `None` on + // /// any error. + // fn timestamp_to_tm(timestamp: i64) -> Option { + // extern "C" { + // #[cfg_attr(target_os = "netbsd", link_name = "__tzset50")] + // fn tzset(); + // } + // + // // The exact type of `timestamp` beforehand can vary, so this + // // conversion is necessary. + // #[allow(clippy::useless_conversion)] + // let timestamp = timestamp.try_into().ok()?; + // + // let mut tm = MaybeUninit::uninit(); + // + // // Update timezone information from system. `localtime_r` does not + // // do this for us. + // // + // // Safety: tzset is thread-safe. + // #[allow(unsafe_code)] + // unsafe { + // tzset(); + // } + // + // // Safety: We are calling a system API, which mutates the `tm` + // // variable. If a null pointer is returned, an error occurred. + // #[allow(unsafe_code)] + // let tm_ptr = unsafe { libc::localtime_r(×tamp, tm.as_mut_ptr()) }; + // + // if tm_ptr.is_null() { + // None + // } else { + // // Safety: The value was initialized, as we no longer have a + // // null pointer. + // #[allow(unsafe_code)] + // { + // Some(unsafe { tm.assume_init() }) + // } + // } + // } + // + // let tm = timestamp_to_tm(datetime.unix_timestamp())?; + // + // // `tm_gmtoff` extension + // #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] + // { + // UtcOffset::seconds(tm.tm_gmtoff.try_into().ok()?).ok() + // } + // + // // No `tm_gmtoff` extension + // #[cfg(any(target_os = "solaris", target_os = "illumos"))] + // { + // use crate::Date; + // use core::convert::TryFrom; + // + // let mut tm = tm; + // if tm.tm_sec == 60 { + // // Leap seconds are not currently supported. + // tm.tm_sec = 59; + // } + // + // let local_timestamp = + // Date::from_yo(1900 + tm.tm_year, u16::try_from(tm.tm_yday).ok()? + 1) + // .ok()? + // .with_hms( + // tm.tm_hour.try_into().ok()?, + // tm.tm_min.try_into().ok()?, + // tm.tm_sec.try_into().ok()?, + // ) + // .ok()? + // .assume_utc() + // .unix_timestamp(); + // + // UtcOffset::seconds( + // (local_timestamp - datetime.unix_timestamp()) + // .try_into() + // .ok()?, + // ) + // .ok() + // } } #[cfg(target_family = "windows")] { diff --git a/tests/offset_date_time.rs b/tests/offset_date_time.rs index cd05ea39a..bf3faad2c 100644 --- a/tests/offset_date_time.rs +++ b/tests/offset_date_time.rs @@ -17,7 +17,7 @@ fn now_utc() { } #[test] -#[cfg(feature = "local-offset")] +#[cfg(all(feature = "local-offset", not(target_family = "unix")))] fn now_local() { assert!(OffsetDateTime::now_local().is_ok()); } diff --git a/tests/utc_offset.rs b/tests/utc_offset.rs index d3bfd1a03..6f7d8e18e 100644 --- a/tests/utc_offset.rs +++ b/tests/utc_offset.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "local-offset")] +#[cfg(all(feature = "local-offset", not(target_family = "unix")))] use time::OffsetDateTime; use time::{Result, UtcOffset}; use time_macros::offset; @@ -125,13 +125,13 @@ fn display() { } #[test] -#[cfg(feature = "local-offset")] +#[cfg(all(feature = "local-offset", not(target_family = "unix")))] fn local_offset_at() { assert!(UtcOffset::local_offset_at(OffsetDateTime::unix_epoch()).is_ok()); } #[test] -#[cfg(feature = "local-offset")] +#[cfg(all(feature = "local-offset", not(target_family = "unix")))] fn current_local_offset() { assert!(UtcOffset::current_local_offset().is_ok()); }