pub struct ZonedDateTime<A, Z>where
A: AsCalendar,{
pub date: Date<A>,
pub time: Time,
pub zone: Z,
}
Expand description
A date and time for a given calendar, local to a specified time zone.
The primary definition of this type is in the icu_time
crate. Other ICU4X crates re-export it for convenience.
Fields§
§date: Date<A>
The date, local to the time zone
time: Time
The time, local to the time zone
zone: Z
The time zone
Implementations§
Source§impl<A> ZonedDateTime<A, UtcOffset>where
A: AsCalendar,
impl<A> ZonedDateTime<A, UtcOffset>where
A: AsCalendar,
Sourcepub fn try_offset_only_from_str(
rfc_9557_str: &str,
calendar: A,
) -> Result<ZonedDateTime<A, UtcOffset>, ParseError>
pub fn try_offset_only_from_str( rfc_9557_str: &str, calendar: A, ) -> Result<ZonedDateTime<A, UtcOffset>, ParseError>
Create a ZonedDateTime
in any calendar from an RFC 9557 string.
Returns an error if the string has a calendar annotation that does not
match the calendar argument, unless the argument is Iso
.
This function is “strict”: the string should have only an offset and no named time zone.
Sourcepub fn try_offset_only_from_utf8(
rfc_9557_str: &[u8],
calendar: A,
) -> Result<ZonedDateTime<A, UtcOffset>, ParseError>
pub fn try_offset_only_from_utf8( rfc_9557_str: &[u8], calendar: A, ) -> Result<ZonedDateTime<A, UtcOffset>, ParseError>
Create a ZonedDateTime
in any calendar from RFC 9557 syntax UTF-8 bytes.
Source§impl<A> ZonedDateTime<A, TimeZoneInfo<AtTime>>where
A: AsCalendar,
impl<A> ZonedDateTime<A, TimeZoneInfo<AtTime>>where
A: AsCalendar,
Sourcepub fn try_location_only_from_str(
rfc_9557_str: &str,
calendar: A,
iana_parser: IanaParserBorrowed<'_>,
) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
pub fn try_location_only_from_str( rfc_9557_str: &str, calendar: A, iana_parser: IanaParserBorrowed<'_>, ) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
Create a ZonedDateTime
in any calendar from an RFC 9557 string.
Returns an error if the string has a calendar annotation that does not
match the calendar argument, unless the argument is Iso
.
This function is “strict”: the string should have only a named time zone and no offset.
Sourcepub fn try_location_only_from_utf8(
rfc_9557_str: &[u8],
calendar: A,
iana_parser: IanaParserBorrowed<'_>,
) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
pub fn try_location_only_from_utf8( rfc_9557_str: &[u8], calendar: A, iana_parser: IanaParserBorrowed<'_>, ) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
Create a ZonedDateTime
in any calendar from RFC 9557 UTF-8 bytes.
Sourcepub fn try_lenient_from_str(
rfc_9557_str: &str,
calendar: A,
iana_parser: IanaParserBorrowed<'_>,
) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
pub fn try_lenient_from_str( rfc_9557_str: &str, calendar: A, iana_parser: IanaParserBorrowed<'_>, ) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
Create a ZonedDateTime
in any calendar from an RFC 9557 string.
Returns an error if the string has a calendar annotation that does not
match the calendar argument, unless the argument is Iso
.
This function is “lenient”: the string can have an offset, and named time zone, both, or neither. If the named time zone is missing, it is returned as Etc/Unknown.
The zone variant is not calculated with this function. If you need it, use
Self::try_full_from_str
.
Sourcepub fn try_lenient_from_utf8(
rfc_9557_str: &[u8],
calendar: A,
iana_parser: IanaParserBorrowed<'_>,
) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
pub fn try_lenient_from_utf8( rfc_9557_str: &[u8], calendar: A, iana_parser: IanaParserBorrowed<'_>, ) -> Result<ZonedDateTime<A, TimeZoneInfo<AtTime>>, ParseError>
Create a ZonedDateTime
in any calendar from RFC 9557 UTF-8 bytes.
Source§impl<A> ZonedDateTime<A, TimeZoneInfo<Full>>where
A: AsCalendar,
impl<A> ZonedDateTime<A, TimeZoneInfo<Full>>where
A: AsCalendar,
Sourcepub fn try_full_from_str(
rfc_9557_str: &str,
calendar: A,
iana_parser: IanaParserBorrowed<'_>,
offset_calculator: VariantOffsetsCalculatorBorrowed<'_>,
) -> Result<ZonedDateTime<A, TimeZoneInfo<Full>>, ParseError>
pub fn try_full_from_str( rfc_9557_str: &str, calendar: A, iana_parser: IanaParserBorrowed<'_>, offset_calculator: VariantOffsetsCalculatorBorrowed<'_>, ) -> Result<ZonedDateTime<A, TimeZoneInfo<Full>>, ParseError>
Create a ZonedDateTime
in any calendar from an RFC 9557 string.
Returns an error if the string has a calendar annotation that does not
match the calendar argument, unless the argument is Iso
.
The string should have both an offset and a named time zone.
For more information on RFC 9557, see the ixdtf
crate.
§Examples
Basic usage:
use icu::calendar::cal::Hebrew;
use icu::locale::subtags::subtag;
use icu::time::{
zone::{
IanaParser, TimeZoneVariant, UtcOffset, VariantOffsetsCalculator,
},
TimeZone, TimeZoneInfo, ZonedDateTime,
};
let zoneddatetime = ZonedDateTime::try_full_from_str(
"2024-08-08T12:08:19-05:00[America/Chicago][u-ca=hebrew]",
Hebrew,
IanaParser::new(),
VariantOffsetsCalculator::new(),
)
.unwrap();
assert_eq!(zoneddatetime.date.extended_year(), 5784);
assert_eq!(
zoneddatetime.date.month().standard_code,
icu::calendar::types::MonthCode(tinystr::tinystr!(4, "M11"))
);
assert_eq!(zoneddatetime.date.day_of_month().0, 4);
assert_eq!(zoneddatetime.time.hour.number(), 12);
assert_eq!(zoneddatetime.time.minute.number(), 8);
assert_eq!(zoneddatetime.time.second.number(), 19);
assert_eq!(zoneddatetime.time.subsecond.number(), 0);
assert_eq!(zoneddatetime.zone.id(), TimeZone(subtag!("uschi")));
assert_eq!(
zoneddatetime.zone.offset(),
Some(UtcOffset::try_from_seconds(-18000).unwrap())
);
assert_eq!(zoneddatetime.zone.variant(), TimeZoneVariant::Daylight);
let _ = zoneddatetime.zone.zone_name_timestamp();
An RFC 9557 string can provide a time zone in two parts: the DateTime UTC Offset or the Time Zone Annotation. A DateTime UTC Offset is the time offset as laid out by RFC 3339; meanwhile, the Time Zone Annotation is the annotation laid out by RFC 9557 and is defined as a UTC offset or IANA Time Zone identifier.
§DateTime UTC Offsets
Below is an example of a time zone from a DateTime UTC Offset. The syntax here is familiar to a RFC 3339 DateTime string.
use icu::calendar::Iso;
use icu::time::{zone::UtcOffset, TimeZoneInfo, ZonedDateTime};
let tz_from_offset = ZonedDateTime::try_offset_only_from_str(
"2024-08-08T12:08:19-05:00",
Iso,
)
.unwrap();
assert_eq!(
tz_from_offset.zone,
UtcOffset::try_from_seconds(-18000).unwrap()
);
§Time Zone Annotations
Below is an example of a time zone being provided by a time zone annotation.
use icu::calendar::Iso;
use icu::locale::subtags::subtag;
use icu::time::{
zone::{IanaParser, TimeZoneVariant, UtcOffset},
TimeZone, TimeZoneInfo, ZonedDateTime,
};
let tz_from_offset_annotation = ZonedDateTime::try_offset_only_from_str(
"2024-08-08T12:08:19[-05:00]",
Iso,
)
.unwrap();
let tz_from_iana_annotation = ZonedDateTime::try_location_only_from_str(
"2024-08-08T12:08:19[America/Chicago]",
Iso,
IanaParser::new(),
)
.unwrap();
assert_eq!(
tz_from_offset_annotation.zone,
UtcOffset::try_from_seconds(-18000).unwrap()
);
assert_eq!(
tz_from_iana_annotation.zone.id(),
TimeZone(subtag!("uschi"))
);
assert_eq!(tz_from_iana_annotation.zone.offset(), None);
§UTC Offset and time zone annotations.
An RFC 9557 string may contain both a UTC Offset and time zone annotation. This is fine as long as the time zone parts can be deemed as inconsistent or unknown consistency.
§UTC Offset with IANA identifier annotation
In cases where the UTC Offset as well as the IANA identifier are provided, some validity checks are performed.
use icu::calendar::Iso;
use icu::time::{TimeZoneInfo, ZonedDateTime, TimeZone, ParseError, zone::{UtcOffset, TimeZoneVariant, IanaParser, VariantOffsetsCalculator}};
use icu::locale::subtags::subtag;
let consistent_tz_from_both = ZonedDateTime::try_full_from_str("2024-08-08T12:08:19-05:00[America/Chicago]", Iso, IanaParser::new(), VariantOffsetsCalculator::new()).unwrap();
assert_eq!(consistent_tz_from_both.zone.id(), TimeZone(subtag!("uschi")));
assert_eq!(consistent_tz_from_both.zone.offset(), Some(UtcOffset::try_from_seconds(-18000).unwrap()));
assert_eq!(consistent_tz_from_both.zone.variant(), TimeZoneVariant::Daylight);
let _ = consistent_tz_from_both.zone.zone_name_timestamp();
// There is no name for America/Los_Angeles at -05:00 (at least in 2024), so either the
// time zone or the offset are wrong.
// The only valid way to display this zoned datetime is "GMT-5", so we drop the time zone.
assert_eq!(
ZonedDateTime::try_full_from_str("2024-08-08T12:08:19-05:00[America/Los_Angeles]", Iso, IanaParser::new(), VariantOffsetsCalculator::new())
.unwrap().zone.id(),
TimeZone::UNKNOWN
);
// We don't know that America/Los_Angeles didn't use standard time (-08:00) in August, but we have a
// name for Los Angeles at -8 (Pacific Standard Time), so this parses successfully.
assert!(
ZonedDateTime::try_full_from_str("2024-08-08T12:08:19-08:00[America/Los_Angeles]", Iso, IanaParser::new(), VariantOffsetsCalculator::new()).is_ok()
);
§DateTime UTC offset with UTC Offset annotation.
These annotations must always be consistent as they should be either the same value or are inconsistent.
use icu::calendar::Iso;
use icu::time::{
zone::UtcOffset, ParseError, TimeZone, TimeZoneInfo, ZonedDateTime,
};
use tinystr::tinystr;
let consistent_tz_from_both = ZonedDateTime::try_offset_only_from_str(
"2024-08-08T12:08:19-05:00[-05:00]",
Iso,
)
.unwrap();
assert_eq!(
consistent_tz_from_both.zone,
UtcOffset::try_from_seconds(-18000).unwrap()
);
let inconsistent_tz_from_both = ZonedDateTime::try_offset_only_from_str(
"2024-08-08T12:08:19-05:00[+05:00]",
Iso,
);
assert!(matches!(
inconsistent_tz_from_both,
Err(ParseError::InconsistentTimeUtcOffsets)
));
Sourcepub fn try_full_from_utf8(
rfc_9557_str: &[u8],
calendar: A,
iana_parser: IanaParserBorrowed<'_>,
offset_calculator: VariantOffsetsCalculatorBorrowed<'_>,
) -> Result<ZonedDateTime<A, TimeZoneInfo<Full>>, ParseError>
pub fn try_full_from_utf8( rfc_9557_str: &[u8], calendar: A, iana_parser: IanaParserBorrowed<'_>, offset_calculator: VariantOffsetsCalculatorBorrowed<'_>, ) -> Result<ZonedDateTime<A, TimeZoneInfo<Full>>, ParseError>
Create a ZonedDateTime
in any calendar from RFC 9557 UTF-8 bytes.
Source§impl ZonedDateTime<Iso, UtcOffset>
impl ZonedDateTime<Iso, UtcOffset>
Sourcepub fn from_epoch_milliseconds_and_utc_offset(
epoch_milliseconds: i64,
utc_offset: UtcOffset,
) -> ZonedDateTime<Iso, UtcOffset>
pub fn from_epoch_milliseconds_and_utc_offset( epoch_milliseconds: i64, utc_offset: UtcOffset, ) -> ZonedDateTime<Iso, UtcOffset>
Creates a ZonedDateTime
from an absolute time, in milliseconds since the UNIX Epoch,
and a UTC offset.
This constructor returns a ZonedDateTime
that supports only the localized offset
time zone style.
§Examples
use icu::calendar::cal::Iso;
use icu::time::zone::UtcOffset;
use icu::time::ZonedDateTime;
let iso_str = "2025-04-30T17:45-0700";
let timestamp = 1746060300000; // milliseconds since UNIX epoch
let offset: UtcOffset = "-0700".parse().unwrap();
let zdt_from_timestamp =
ZonedDateTime::from_epoch_milliseconds_and_utc_offset(
timestamp, offset,
);
// Check that it equals the same as the parse result:
let zdt_from_str =
ZonedDateTime::try_offset_only_from_str(iso_str, Iso).unwrap();
assert_eq!(zdt_from_timestamp, zdt_from_str);
Negative timestamps are supported:
use icu::calendar::cal::Iso;
use icu::time::zone::UtcOffset;
use icu::time::ZonedDateTime;
let iso_str = "1920-01-02T03:04:05.250+0600";
let timestamp = -1577847354750; // milliseconds since UNIX epoch
let offset: UtcOffset = "+0600".parse().unwrap();
let zdt_from_timestamp =
ZonedDateTime::from_epoch_milliseconds_and_utc_offset(
timestamp, offset,
);
// Check that it equals the same as the parse result:
let zdt_from_str =
ZonedDateTime::try_offset_only_from_str(iso_str, Iso).unwrap();
assert_eq!(zdt_from_timestamp, zdt_from_str);
Trait Implementations§
Source§impl<A, Z> Clone for ZonedDateTime<A, Z>
impl<A, Z> Clone for ZonedDateTime<A, Z>
Source§fn clone(&self) -> ZonedDateTime<A, Z>
fn clone(&self) -> ZonedDateTime<A, Z>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<C, A, Z> ConvertCalendar for ZonedDateTime<A, Z>
impl<C, A, Z> ConvertCalendar for ZonedDateTime<A, Z>
Source§type Converted<'a> = ZonedDateTime<Ref<'a, AnyCalendar>, Z>
type Converted<'a> = ZonedDateTime<Ref<'a, AnyCalendar>, Z>
Source§fn to_calendar<'a>(
&self,
calendar: &'a AnyCalendar,
) -> <ZonedDateTime<A, Z> as ConvertCalendar>::Converted<'a>
fn to_calendar<'a>( &self, calendar: &'a AnyCalendar, ) -> <ZonedDateTime<A, Z> as ConvertCalendar>::Converted<'a>
self
to the specified AnyCalendar
.Source§impl<A, Z> Debug for ZonedDateTime<A, Z>
impl<A, Z> Debug for ZonedDateTime<A, Z>
Source§impl<C, A, Z> GetField<()> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<()> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<DayOfMonth> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<DayOfMonth> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§fn get_field(&self) -> DayOfMonth
fn get_field(&self) -> DayOfMonth
T
.Source§impl<C, A, Z> GetField<DayOfYear> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<DayOfYear> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<Hour> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<Hour> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<Minute> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<Minute> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<MonthInfo> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<MonthInfo> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<Nanosecond> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<Nanosecond> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§fn get_field(&self) -> Nanosecond
fn get_field(&self) -> Nanosecond
T
.Source§impl<C, A, Z> GetField<Second> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<Second> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<TimeZone> for ZonedDateTime<A, Z>
impl<C, A, Z> GetField<TimeZone> for ZonedDateTime<A, Z>
Source§impl<C, A, Z> GetField<TimeZoneVariant> for ZonedDateTime<A, Z>
impl<C, A, Z> GetField<TimeZoneVariant> for ZonedDateTime<A, Z>
Source§fn get_field(&self) -> TimeZoneVariant
fn get_field(&self) -> TimeZoneVariant
T
.Source§impl<C, A, Z> GetField<Weekday> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<Weekday> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<YearInfo> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> GetField<YearInfo> for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Source§impl<C, A, Z> GetField<ZoneNameTimestamp> for ZonedDateTime<A, Z>
impl<C, A, Z> GetField<ZoneNameTimestamp> for ZonedDateTime<A, Z>
Source§fn get_field(&self) -> ZoneNameTimestamp
fn get_field(&self) -> ZoneNameTimestamp
T
.Source§impl<C, A, Z> InSameCalendar for ZonedDateTime<A, Z>where
C: IntoAnyCalendar,
A: AsCalendar<Calendar = C>,
impl<C, A, Z> InSameCalendar for ZonedDateTime<A, Z>where
C: IntoAnyCalendar,
A: AsCalendar<Calendar = C>,
Source§fn check_any_calendar_kind(
&self,
any_calendar_kind: AnyCalendarKind,
) -> Result<(), MismatchedCalendarError>
fn check_any_calendar_kind( &self, any_calendar_kind: AnyCalendarKind, ) -> Result<(), MismatchedCalendarError>
Source§impl<A, Z> PartialEq for ZonedDateTime<A, Z>
impl<A, Z> PartialEq for ZonedDateTime<A, Z>
impl<A, Z> Copy for ZonedDateTime<A, Z>
impl<A, Z> Eq for ZonedDateTime<A, Z>
impl<C, A, Z> InFixedCalendar<C> for ZonedDateTime<A, Z>where
C: CldrCalendar,
A: AsCalendar<Calendar = C>,
impl<A, Z> StructuralPartialEq for ZonedDateTime<A, Z>where
A: AsCalendar,
impl<C, A, Z> UnstableSealed for ZonedDateTime<A, Z>where
C: Calendar,
A: AsCalendar<Calendar = C>,
Auto Trait Implementations§
impl<A, Z> Freeze for ZonedDateTime<A, Z>
impl<A, Z> RefUnwindSafe for ZonedDateTime<A, Z>where
Z: RefUnwindSafe,
<<A as AsCalendar>::Calendar as Calendar>::DateInner: RefUnwindSafe,
A: RefUnwindSafe,
impl<A, Z> Send for ZonedDateTime<A, Z>
impl<A, Z> Sync for ZonedDateTime<A, Z>
impl<A, Z> Unpin for ZonedDateTime<A, Z>
impl<A, Z> UnwindSafe for ZonedDateTime<A, Z>where
Z: UnwindSafe,
<<A as AsCalendar>::Calendar as Calendar>::DateInner: UnwindSafe,
A: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> GetField<T> for Twhere
T: Copy + UnstableSealed,
impl<T> GetField<T> for Twhere
T: Copy + UnstableSealed,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more