summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/offset/local/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chrono/src/offset/local/mod.rs')
-rw-r--r--vendor/chrono/src/offset/local/mod.rs260
1 files changed, 260 insertions, 0 deletions
diff --git a/vendor/chrono/src/offset/local/mod.rs b/vendor/chrono/src/offset/local/mod.rs
new file mode 100644
index 000000000..e280c7800
--- /dev/null
+++ b/vendor/chrono/src/offset/local/mod.rs
@@ -0,0 +1,260 @@
+// This is a part of Chrono.
+// See README.md and LICENSE.txt for details.
+
+//! The local (system) time zone.
+
+#[cfg(feature = "rkyv")]
+use rkyv::{Archive, Deserialize, Serialize};
+
+use super::fixed::FixedOffset;
+use super::{LocalResult, TimeZone};
+use crate::naive::{NaiveDate, NaiveDateTime};
+#[allow(deprecated)]
+use crate::{Date, DateTime};
+
+// we don't want `stub.rs` when the target_os is not wasi or emscripten
+// as we use js-sys to get the date instead
+#[cfg(all(
+ not(unix),
+ not(windows),
+ not(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ ))
+))]
+#[path = "stub.rs"]
+mod inner;
+
+#[cfg(unix)]
+#[path = "unix.rs"]
+mod inner;
+
+#[cfg(windows)]
+#[path = "windows.rs"]
+mod inner;
+
+#[cfg(unix)]
+mod tz_info;
+
+/// The local timescale. This is implemented via the standard `time` crate.
+///
+/// Using the [`TimeZone`](./trait.TimeZone.html) methods
+/// on the Local struct is the preferred way to construct `DateTime<Local>`
+/// instances.
+///
+/// # Example
+///
+/// ```
+/// use chrono::{Local, DateTime, TimeZone};
+///
+/// let dt: DateTime<Local> = Local::now();
+/// let dt: DateTime<Local> = Local.timestamp(0, 0);
+/// ```
+#[derive(Copy, Clone, Debug)]
+#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
+#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
+pub struct Local;
+
+impl Local {
+ /// Returns a `Date` which corresponds to the current date.
+ #[deprecated(since = "0.4.23", note = "use `Local::now()` instead")]
+ #[allow(deprecated)]
+ pub fn today() -> Date<Local> {
+ Local::now().date()
+ }
+
+ /// Returns a `DateTime` which corresponds to the current date and time.
+ #[cfg(not(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ )))]
+ pub fn now() -> DateTime<Local> {
+ inner::now()
+ }
+
+ /// Returns a `DateTime` which corresponds to the current date and time.
+ #[cfg(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ ))]
+ pub fn now() -> DateTime<Local> {
+ use super::Utc;
+ let now: DateTime<Utc> = super::Utc::now();
+
+ // Workaround missing timezone logic in `time` crate
+ let offset =
+ FixedOffset::west_opt((js_sys::Date::new_0().get_timezone_offset() as i32) * 60)
+ .unwrap();
+ DateTime::from_utc(now.naive_utc(), offset)
+ }
+}
+
+impl TimeZone for Local {
+ type Offset = FixedOffset;
+
+ fn from_offset(_offset: &FixedOffset) -> Local {
+ Local
+ }
+
+ // they are easier to define in terms of the finished date and time unlike other offsets
+ #[allow(deprecated)]
+ fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<FixedOffset> {
+ self.from_local_date(local).map(|date| *date.offset())
+ }
+
+ fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<FixedOffset> {
+ self.from_local_datetime(local).map(|datetime| *datetime.offset())
+ }
+
+ #[allow(deprecated)]
+ fn offset_from_utc_date(&self, utc: &NaiveDate) -> FixedOffset {
+ *self.from_utc_date(utc).offset()
+ }
+
+ fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> FixedOffset {
+ *self.from_utc_datetime(utc).offset()
+ }
+
+ // override them for avoiding redundant works
+ #[allow(deprecated)]
+ fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<Local>> {
+ // this sounds very strange, but required for keeping `TimeZone::ymd` sane.
+ // in the other words, we use the offset at the local midnight
+ // but keep the actual date unaltered (much like `FixedOffset`).
+ let midnight = self.from_local_datetime(&local.and_hms_opt(0, 0, 0).unwrap());
+ midnight.map(|datetime| Date::from_utc(*local, *datetime.offset()))
+ }
+
+ #[cfg(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ ))]
+ fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
+ let mut local = local.clone();
+ // Get the offset from the js runtime
+ let offset =
+ FixedOffset::west_opt((js_sys::Date::new_0().get_timezone_offset() as i32) * 60)
+ .unwrap();
+ local -= crate::Duration::seconds(offset.local_minus_utc() as i64);
+ LocalResult::Single(DateTime::from_utc(local, offset))
+ }
+
+ #[cfg(not(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ )))]
+ fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
+ inner::naive_to_local(local, true)
+ }
+
+ #[allow(deprecated)]
+ fn from_utc_date(&self, utc: &NaiveDate) -> Date<Local> {
+ let midnight = self.from_utc_datetime(&utc.and_hms_opt(0, 0, 0).unwrap());
+ Date::from_utc(*utc, *midnight.offset())
+ }
+
+ #[cfg(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ ))]
+ fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
+ // Get the offset from the js runtime
+ let offset =
+ FixedOffset::west_opt((js_sys::Date::new_0().get_timezone_offset() as i32) * 60)
+ .unwrap();
+ DateTime::from_utc(*utc, offset)
+ }
+
+ #[cfg(not(all(
+ target_arch = "wasm32",
+ feature = "wasmbind",
+ not(any(target_os = "emscripten", target_os = "wasi"))
+ )))]
+ fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
+ // this is OK to unwrap as getting local time from a UTC
+ // timestamp is never ambiguous
+ inner::naive_to_local(utc, false).unwrap()
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Local;
+ use crate::offset::TimeZone;
+ use crate::{Datelike, Duration, Utc};
+
+ #[test]
+ fn verify_correct_offsets() {
+ let now = Local::now();
+ let from_local = Local.from_local_datetime(&now.naive_local()).unwrap();
+ let from_utc = Local.from_utc_datetime(&now.naive_utc());
+
+ assert_eq!(now.offset().local_minus_utc(), from_local.offset().local_minus_utc());
+ assert_eq!(now.offset().local_minus_utc(), from_utc.offset().local_minus_utc());
+
+ assert_eq!(now, from_local);
+ assert_eq!(now, from_utc);
+ }
+
+ #[test]
+ fn verify_correct_offsets_distant_past() {
+ // let distant_past = Local::now() - Duration::days(365 * 100);
+ let distant_past = Local::now() - Duration::days(250 * 31);
+ let from_local = Local.from_local_datetime(&distant_past.naive_local()).unwrap();
+ let from_utc = Local.from_utc_datetime(&distant_past.naive_utc());
+
+ assert_eq!(distant_past.offset().local_minus_utc(), from_local.offset().local_minus_utc());
+ assert_eq!(distant_past.offset().local_minus_utc(), from_utc.offset().local_minus_utc());
+
+ assert_eq!(distant_past, from_local);
+ assert_eq!(distant_past, from_utc);
+ }
+
+ #[test]
+ fn verify_correct_offsets_distant_future() {
+ let distant_future = Local::now() + Duration::days(250 * 31);
+ let from_local = Local.from_local_datetime(&distant_future.naive_local()).unwrap();
+ let from_utc = Local.from_utc_datetime(&distant_future.naive_utc());
+
+ assert_eq!(
+ distant_future.offset().local_minus_utc(),
+ from_local.offset().local_minus_utc()
+ );
+ assert_eq!(distant_future.offset().local_minus_utc(), from_utc.offset().local_minus_utc());
+
+ assert_eq!(distant_future, from_local);
+ assert_eq!(distant_future, from_utc);
+ }
+
+ #[test]
+ fn test_local_date_sanity_check() {
+ // issue #27
+ assert_eq!(Local.with_ymd_and_hms(2999, 12, 28, 0, 0, 0).unwrap().day(), 28);
+ }
+
+ #[test]
+ fn test_leap_second() {
+ // issue #123
+ let today = Utc::now().date_naive();
+
+ let dt = today.and_hms_milli_opt(1, 2, 59, 1000).unwrap();
+ let timestr = dt.time().to_string();
+ // the OS API may or may not support the leap second,
+ // but there are only two sensible options.
+ assert!(timestr == "01:02:60" || timestr == "01:03:00", "unexpected timestr {:?}", timestr);
+
+ let dt = today.and_hms_milli_opt(1, 2, 3, 1234).unwrap();
+ let timestr = dt.time().to_string();
+ assert!(
+ timestr == "01:02:03.234" || timestr == "01:02:04.234",
+ "unexpected timestr {:?}",
+ timestr
+ );
+ }
+}