devela::_dep::jiff::fmt::strtime

Struct BrokenDownTime

pub struct BrokenDownTime { /* private fields */ }
Available on crate features dep_jiff and alloc only.
Expand description

The “broken down time” used by parsing and formatting.

This is a lower level aspect of the strptime and strftime APIs that you probably won’t need to use directly. The main use case is if you want to observe formatting errors or if you want to format a datetime to something other than a String via the fmt::Write trait.

Otherwise, typical use of this module happens indirectly via APIs like Zoned::strptime and Zoned::strftime.

§Design

This is the type that parsing writes to and formatting reads from. That is, parsing proceeds by writing individual parsed fields to this type, and then converting the fields to datetime types like Zoned only after parsing is complete. Similarly, formatting always begins by converting datetime types like Zoned into a BrokenDownTime, and then formatting the individual fields from there.

Implementations§

§

impl BrokenDownTime

pub fn parse( format: impl AsRef<[u8]>, input: impl AsRef<[u8]>, ) -> Result<BrokenDownTime, Error>

Parse the given input according to the given format string.

See the module documentation for details on what’s supported.

This routine is the same as the module level free function strtime::parse.

§Errors

This returns an error when parsing failed. This might happen because the format string itself was invalid, or because the input didn’t match the format string.

§Example
use jiff::{civil, fmt::strtime::BrokenDownTime};

let tm = BrokenDownTime::parse("%m/%d/%y", "7/14/24")?;
let date = tm.to_date()?;
assert_eq!(date, civil::date(2024, 7, 14));

pub fn format<W>(&self, format: impl AsRef<[u8]>, wtr: W) -> Result<(), Error>
where W: Write,

Format this broken down time using the format string given.

See the module documentation for details on what’s supported.

This routine is like the module level free function strtime::format, except it takes a fmt::Write trait implementations instead of assuming you want a String.

§Errors

This returns an error when formatting failed. Formatting can fail either because of an invalid format string, or if formatting requires a field in BrokenDownTime to be set that isn’t. For example, trying to format a DateTime with the %z specifier will fail because a DateTime has no time zone or offset information associated with it.

Formatting also fails if writing to the given writer fails.

§Example

This example shows a formatting option, %Z, that isn’t available during parsing. Namely, %Z inserts a time zone abbreviation. This is generally only intended for display purposes, since it can be ambiguous when parsing.

use jiff::{civil::date, fmt::strtime::BrokenDownTime};

let zdt = date(2024, 7, 9).at(16, 24, 0, 0).intz("America/New_York")?;
let tm = BrokenDownTime::from(&zdt);

let mut buf = String::new();
tm.format("%a %b %e %I:%M:%S %p %Z %Y", &mut buf)?;

assert_eq!(buf, "Tue Jul  9 04:24:00 PM EDT 2024");

pub fn to_string(&self, format: impl AsRef<[u8]>) -> Result<String, Error>

Format this broken down time using the format string given into a new String.

See the module documentation for details on what’s supported.

This is like BrokenDownTime::format, but always uses a String to format the time into. If you need to reuse allocations or write a formatted time into a different type, then you should use BrokenDownTime::format instead.

§Errors

This returns an error when formatting failed. Formatting can fail either because of an invalid format string, or if formatting requires a field in BrokenDownTime to be set that isn’t. For example, trying to format a DateTime with the %z specifier will fail because a DateTime has no time zone or offset information associated with it.

§Example

This example shows a formatting option, %Z, that isn’t available during parsing. Namely, %Z inserts a time zone abbreviation. This is generally only intended for display purposes, since it can be ambiguous when parsing.

use jiff::{civil::date, fmt::strtime::BrokenDownTime};

let zdt = date(2024, 7, 9).at(16, 24, 0, 0).intz("America/New_York")?;
let tm = BrokenDownTime::from(&zdt);
let string = tm.to_string("%a %b %e %I:%M:%S %p %Z %Y")?;
assert_eq!(string, "Tue Jul  9 04:24:00 PM EDT 2024");

pub fn to_zoned(&self) -> Result<Zoned, Error>

Extracts a zoned datetime from this broken down time.

When an IANA time zone identifier is present but an offset is not, then the Disambiguation::Compatible strategy is used if the parsed datetime is ambiguous in the time zone.

If you need to use a custom time zone database for doing IANA time zone identifier lookups (via the %V directive), then use BrokenDownTime::to_zoned_with.

§Warning

The strtime module APIs do not require an IANA time zone identifier to parse a Zoned. If one is not used, then if you format a zoned datetime in a time zone like America/New_York and then parse it back again, the zoned datetime you get back will be a “fixed offset” zoned datetime. This in turn means it will not perform daylight saving time safe arithmetic.

However, the %V directive may be used to both format and parse an IANA time zone identifier. It is strongly recommended to use this directive whenever one is formatting or parsing Zoned values.

§Errors

This returns an error if there weren’t enough components to construct a civil datetime and either a UTC offset or a IANA time zone identifier. When both a UTC offset and an IANA time zone identifier are found, then OffsetConflict::Reject is used to detect any inconsistency between the offset and the time zone.

§Example

This example shows how to parse a zoned datetime:

use jiff::fmt::strtime;

let zdt = strtime::parse(
    "%F %H:%M %:z %:V",
    "2024-07-14 21:14 -04:00 US/Eastern",
)?.to_zoned()?;
assert_eq!(zdt.to_string(), "2024-07-14T21:14:00-04:00[US/Eastern]");

This shows that an error is returned when the offset is inconsistent with the time zone. For example, US/Eastern is in daylight saving time in July 2024:

use jiff::fmt::strtime;

let result = strtime::parse(
    "%F %H:%M %:z %:V",
    "2024-07-14 21:14 -05:00 US/Eastern",
)?.to_zoned();
assert_eq!(
    result.unwrap_err().to_string(),
    "datetime 2024-07-14T21:14:00 could not resolve to a \
     timestamp since 'reject' conflict resolution was chosen, \
     and because datetime has offset -05, but the time zone \
     US/Eastern for the given datetime unambiguously has offset -04",
);

pub fn to_zoned_with(&self, db: &TimeZoneDatabase) -> Result<Zoned, Error>

Extracts a zoned datetime from this broken down time and uses the time zone database given for any IANA time zone identifier lookups.

An IANA time zone identifier lookup is only performed when this BrokenDownTime contains an IANA time zone identifier. An IANA time zone identifier can be parsed with the %V directive.

When an IANA time zone identifier is present but an offset is not, then the Disambiguation::Compatible strategy is used if the parsed datetime is ambiguous in the time zone.

§Warning

The strtime module APIs do not require an IANA time zone identifier to parse a Zoned. If one is not used, then if you format a zoned datetime in a time zone like America/New_York and then parse it back again, the zoned datetime you get back will be a “fixed offset” zoned datetime. This in turn means it will not perform daylight saving time safe arithmetic.

However, the %V directive may be used to both format and parse an IANA time zone identifier. It is strongly recommended to use this directive whenever one is formatting or parsing Zoned values.

§Errors

This returns an error if there weren’t enough components to construct a civil datetime and either a UTC offset or a IANA time zone identifier. When both a UTC offset and an IANA time zone identifier are found, then OffsetConflict::Reject is used to detect any inconsistency between the offset and the time zone.

§Example

This example shows how to parse a zoned datetime:

use jiff::fmt::strtime;

let zdt = strtime::parse(
    "%F %H:%M %:z %:V",
    "2024-07-14 21:14 -04:00 US/Eastern",
)?.to_zoned_with(jiff::tz::db())?;
assert_eq!(zdt.to_string(), "2024-07-14T21:14:00-04:00[US/Eastern]");

pub fn to_timestamp(&self) -> Result<Timestamp, Error>

Extracts a timestamp from this broken down time.

§Errors

This returns an error if there weren’t enough components to construct a civil datetime and a UTC offset.

§Example

This example shows how to parse a timestamp from a broken down time:

use jiff::fmt::strtime;

let ts = strtime::parse(
    "%F %H:%M %:z",
    "2024-07-14 21:14 -04:00",
)?.to_timestamp()?;
assert_eq!(ts.to_string(), "2024-07-15T01:14:00Z");

pub fn to_datetime(&self) -> Result<DateTime, Error>

Extracts a civil datetime from this broken down time.

§Errors

This returns an error if there weren’t enough components to construct a civil datetime. This means there must be at least a year, month and day.

It’s okay if there are more units than are needed to construct a civil datetime. For example, if this broken down time contains an offset, then it won’t prevent a conversion to a civil datetime.

§Example

This example shows how to parse a civil datetime from a broken down time:

use jiff::fmt::strtime;

let dt = strtime::parse("%F %H:%M", "2024-07-14 21:14")?.to_datetime()?;
assert_eq!(dt.to_string(), "2024-07-14T21:14:00");

pub fn to_date(&self) -> Result<Date, Error>

Extracts a civil date from this broken down time.

§Errors

This returns an error if there weren’t enough components to construct a civil date. This means there must be at least a year, month and day.

It’s okay if there are more units than are needed to construct a civil datetime. For example, if this broken down time contain a civil time, then it won’t prevent a conversion to a civil date.

§Example

This example shows how to parse a civil date from a broken down time:

use jiff::fmt::strtime;

let date = strtime::parse("%m/%d/%y", "7/14/24")?.to_date()?;
assert_eq!(date.to_string(), "2024-07-14");

pub fn to_time(&self) -> Result<Time, Error>

Extracts a civil time from this broken down time.

§Errors

This returns an error if there weren’t enough components to construct a civil time. Interestingly, this succeeds if there are no time units, since this will assume an absent time is midnight. However, this can still error when, for example, there are minutes but no hours.

It’s okay if there are more units than are needed to construct a civil time. For example, if this broken down time contains a date, then it won’t prevent a conversion to a civil time.

§Example

This example shows how to parse a civil time from a broken down time:

use jiff::fmt::strtime;

let time = strtime::parse("%H:%M:%S", "21:14:59")?.to_time()?;
assert_eq!(time.to_string(), "21:14:59");
§Example: time defaults to midnight

Since time defaults to midnight, one can parse an empty input string with an empty format string and still extract a Time:

use jiff::fmt::strtime;

let time = strtime::parse("", "")?.to_time()?;
assert_eq!(time.to_string(), "00:00:00");
§Example: invalid time

Other than using illegal values (like 24 for hours), if lower units are parsed without higher units, then this results in an error:

use jiff::fmt::strtime;

assert!(strtime::parse("%M:%S", "15:36")?.to_time().is_err());
§Example: invalid date

Since validation of a date is only done when a date is requested, it is actually possible to parse an invalid date and extract the time without an error occurring:

use jiff::fmt::strtime;

// 31 is a legal day value, but not for June.
// However, this is not validated unless you
// ask for a `Date` from the parsed `BrokenDownTime`.
// Everything except for `BrokenDownTime::time`
// creates a date, so asking for only a `time`
// will circumvent date validation!
let tm = strtime::parse("%Y-%m-%d %H:%M:%S", "2024-06-31 21:14:59")?;
let time = tm.to_time()?;
assert_eq!(time.to_string(), "21:14:59");

pub fn year(&self) -> Option<i16>

Returns the parsed year, if available.

This is also set when a 2 digit year is parsed. (But that’s limited to the years 1969 to 2068, inclusive.)

§Example

This shows how to parse just a year:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%Y", "2024")?;
assert_eq!(tm.year(), Some(2024));

And 2-digit years are supported too:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%y", "24")?;
assert_eq!(tm.year(), Some(2024));
let tm = BrokenDownTime::parse("%y", "00")?;
assert_eq!(tm.year(), Some(2000));
let tm = BrokenDownTime::parse("%y", "69")?;
assert_eq!(tm.year(), Some(1969));

// 2-digit years have limited range. They must
// be in the range 0-99.
assert!(BrokenDownTime::parse("%y", "2024").is_err());

pub fn month(&self) -> Option<i8>

Returns the parsed month, if available.

§Example

This shows a few different ways of parsing just a month:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%m", "12")?;
assert_eq!(tm.month(), Some(12));

let tm = BrokenDownTime::parse("%B", "December")?;
assert_eq!(tm.month(), Some(12));

let tm = BrokenDownTime::parse("%b", "Dec")?;
assert_eq!(tm.month(), Some(12));

pub fn day(&self) -> Option<i8>

Returns the parsed day, if available.

§Example

This shows how to parse the day of the month:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%d", "5")?;
assert_eq!(tm.day(), Some(5));

let tm = BrokenDownTime::parse("%d", "05")?;
assert_eq!(tm.day(), Some(5));

let tm = BrokenDownTime::parse("%03d", "005")?;
assert_eq!(tm.day(), Some(5));

// Parsing a day only works for all possible legal
// values, even if, e.g., 31 isn't valid for all
// possible year/month combinations.
let tm = BrokenDownTime::parse("%d", "31")?;
assert_eq!(tm.day(), Some(31));
// This is true even if you're parsing a full date:
let tm = BrokenDownTime::parse("%Y-%m-%d", "2024-04-31")?;
assert_eq!(tm.day(), Some(31));
// An error only occurs when you try to extract a date:
assert!(tm.to_date().is_err());
// But parsing a value that is always illegal will
// result in an error:
assert!(BrokenDownTime::parse("%d", "32").is_err());

pub fn hour(&self) -> Option<i8>

Returns the parsed hour, if available.

The hour returned incorporates BrokenDownTime::meridiem if it’s set. That is, if the actual parsed hour value is 1 but the meridiem is PM, then the hour returned by this method will be 13.

§Example

This shows a how to parse an hour:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%H", "13")?;
assert_eq!(tm.hour(), Some(13));

// When parsing a 12-hour clock without a
// meridiem, the hour value is as parsed.
let tm = BrokenDownTime::parse("%I", "1")?;
assert_eq!(tm.hour(), Some(1));

// If a meridiem is parsed, then it is used
// to calculate the correct hour value.
let tm = BrokenDownTime::parse("%I%P", "1pm")?;
assert_eq!(tm.hour(), Some(13));

// This works even if the hour and meridiem are
// inconsistent with each other:
let tm = BrokenDownTime::parse("%H%P", "13am")?;
assert_eq!(tm.hour(), Some(1));

pub fn minute(&self) -> Option<i8>

Returns the parsed minute, if available.

§Example

This shows how to parse the minute:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%M", "5")?;
assert_eq!(tm.minute(), Some(5));

pub fn second(&self) -> Option<i8>

Returns the parsed second, if available.

§Example

This shows how to parse the second:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%S", "5")?;
assert_eq!(tm.second(), Some(5));

pub fn subsec_nanosecond(&self) -> Option<i32>

Returns the parsed subsecond nanosecond, if available.

§Example

This shows how to parse fractional seconds:

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%f", "123456")?;
assert_eq!(tm.subsec_nanosecond(), Some(123_456_000));

Note that when using %.f, the fractional component is optional!

use jiff::fmt::strtime::BrokenDownTime;

let tm = BrokenDownTime::parse("%S%.f", "1")?;
assert_eq!(tm.second(), Some(1));
assert_eq!(tm.subsec_nanosecond(), None);

let tm = BrokenDownTime::parse("%S%.f", "1.789")?;
assert_eq!(tm.second(), Some(1));
assert_eq!(tm.subsec_nanosecond(), Some(789_000_000));

pub fn offset(&self) -> Option<Offset>

Returns the parsed offset, if available.

§Example

This shows how to parse the offset:

use jiff::{fmt::strtime::BrokenDownTime, tz::Offset};

let tm = BrokenDownTime::parse("%z", "-0430")?;
assert_eq!(
    tm.offset(),
    Some(Offset::from_seconds(-4 * 60 * 60 - 30 * 60).unwrap()),
);
let tm = BrokenDownTime::parse("%z", "-043059")?;
assert_eq!(
    tm.offset(),
    Some(Offset::from_seconds(-4 * 60 * 60 - 30 * 60 - 59).unwrap()),
);

// Or, if you want colons:
let tm = BrokenDownTime::parse("%:z", "-04:30")?;
assert_eq!(
    tm.offset(),
    Some(Offset::from_seconds(-4 * 60 * 60 - 30 * 60).unwrap()),
);

pub fn iana_time_zone(&self) -> Option<&str>

Returns the time zone IANA identifier, if available.

Note that when alloc is disabled, this always returns None. (And there is no way to set it.)

§Example

This shows how to parse an IANA time zone identifier:

use jiff::{fmt::strtime::BrokenDownTime, tz};

let tm = BrokenDownTime::parse("%V", "US/Eastern")?;
assert_eq!(tm.iana_time_zone(), Some("US/Eastern"));
assert_eq!(tm.offset(), None);

// Note that %V (and %:V) also support parsing an offset
// as a fallback. If that occurs, an IANA time zone
// identifier is not available.
let tm = BrokenDownTime::parse("%V", "-0400")?;
assert_eq!(tm.iana_time_zone(), None);
assert_eq!(tm.offset(), Some(tz::offset(-4)));

pub fn weekday(&self) -> Option<Weekday>

Returns the parsed weekday, if available.

§Example

This shows a few different ways of parsing just a weekday:

use jiff::{civil::Weekday, fmt::strtime::BrokenDownTime};

let tm = BrokenDownTime::parse("%A", "Saturday")?;
assert_eq!(tm.weekday(), Some(Weekday::Saturday));

let tm = BrokenDownTime::parse("%a", "Sat")?;
assert_eq!(tm.weekday(), Some(Weekday::Saturday));

// A weekday is only available if it is explicitly parsed!
let tm = BrokenDownTime::parse("%F", "2024-07-27")?;
assert_eq!(tm.weekday(), None);
// If you need a weekday derived from a parsed date, then:
assert_eq!(tm.to_date()?.weekday(), Weekday::Saturday);

Note that this will return the parsed weekday even if it’s inconsistent with a parsed date:

use jiff::{civil::{Weekday, date}, fmt::strtime::BrokenDownTime};

let mut tm = BrokenDownTime::parse("%a, %F", "Wed, 2024-07-27")?;
// 2024-07-27 is a Saturday, but Wednesday was parsed:
assert_eq!(tm.weekday(), Some(Weekday::Wednesday));
// An error only occurs when extracting a date:
assert!(tm.to_date().is_err());
// To skip the weekday, error checking, zero it out first:
tm.set_weekday(None);
assert_eq!(tm.to_date()?, date(2024, 7, 27));

pub fn meridiem(&self) -> Option<Meridiem>

Returns the parsed meridiem, if available.

Note that unlike other fields, there is no BrokenDownTime::set_meridiem. Instead, when formatting, the meridiem label (if it’s used in the formatting string) is determined purely as a function of the hour in a 24 hour clock.

§Example

This shows a how to parse the meridiem:

use jiff::fmt::strtime::{BrokenDownTime, Meridiem};

let tm = BrokenDownTime::parse("%p", "AM")?;
assert_eq!(tm.meridiem(), Some(Meridiem::AM));
let tm = BrokenDownTime::parse("%P", "pm")?;
assert_eq!(tm.meridiem(), Some(Meridiem::PM));

pub fn set_year(&mut self, year: Option<i16>) -> Result<(), Error>

Set the year on this broken down time.

§Errors

This returns an error if the given year is out of range.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_year(Some(10_000)).is_err());
tm.set_year(Some(2024))?;
assert_eq!(tm.to_string("%Y")?, "2024");

pub fn set_month(&mut self, month: Option<i8>) -> Result<(), Error>

Set the month on this broken down time.

§Errors

This returns an error if the given month is out of range.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_month(Some(0)).is_err());
tm.set_month(Some(12))?;
assert_eq!(tm.to_string("%B")?, "December");

pub fn set_day(&mut self, day: Option<i8>) -> Result<(), Error>

Set the day on this broken down time.

§Errors

This returns an error if the given day is out of range.

Note that setting a day to a value that is legal in any context is always valid, even if it isn’t valid for the year and month components already set.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_day(Some(32)).is_err());
tm.set_day(Some(31))?;
assert_eq!(tm.to_string("%d")?, "31");

// Works even if the resulting date is invalid.
let mut tm = BrokenDownTime::default();
tm.set_year(Some(2024))?;
tm.set_month(Some(4))?;
tm.set_day(Some(31))?; // April has 30 days, not 31
assert_eq!(tm.to_string("%F")?, "2024-04-31");

pub fn set_hour(&mut self, hour: Option<i8>) -> Result<(), Error>

Set the hour on this broken down time.

§Errors

This returns an error if the given hour is out of range.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_hour(Some(24)).is_err());
tm.set_hour(Some(0))?;
assert_eq!(tm.to_string("%H")?, "00");
assert_eq!(tm.to_string("%-H")?, "0");

pub fn set_minute(&mut self, minute: Option<i8>) -> Result<(), Error>

Set the minute on this broken down time.

§Errors

This returns an error if the given minute is out of range.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_minute(Some(60)).is_err());
tm.set_minute(Some(59))?;
assert_eq!(tm.to_string("%M")?, "59");
assert_eq!(tm.to_string("%03M")?, "059");
assert_eq!(tm.to_string("%_3M")?, " 59");

pub fn set_second(&mut self, second: Option<i8>) -> Result<(), Error>

Set the second on this broken down time.

§Errors

This returns an error if the given second is out of range.

Jiff does not support leap seconds, so the range of valid seconds is 0 to 59, inclusive. Note though that when parsing, a parsed value of 60 is automatically constrained to 59.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_second(Some(60)).is_err());
tm.set_second(Some(59))?;
assert_eq!(tm.to_string("%S")?, "59");

pub fn set_subsec_nanosecond( &mut self, subsec_nanosecond: Option<i32>, ) -> Result<(), Error>

Set the subsecond nanosecond on this broken down time.

§Errors

This returns an error if the given number of nanoseconds is out of range. It must be non-negative and less than 1 whole second.

§Example
use jiff::fmt::strtime::BrokenDownTime;

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_subsec_nanosecond(Some(1_000_000_000)).is_err());
tm.set_subsec_nanosecond(Some(123_000_000))?;
assert_eq!(tm.to_string("%f")?, "123");
assert_eq!(tm.to_string("%.6f")?, ".123000");

pub fn set_offset(&mut self, offset: Option<Offset>)

Set the time zone offset on this broken down time.

This can be useful for setting the offset after parsing if the offset is known from the context or from some out-of-band information.

Note that one can set any legal offset value, regardless of whether it’s consistent with the IANA time zone identifier on this broken down time (if it’s set). Similarly, setting the offset does not actually change any other value in this broken down time.

§Example: setting the offset after parsing

One use case for this routine is when parsing a datetime without an offset, but where one wants to set an offset based on the context. For example, while it’s usually not correct to assume a datetime is in UTC, if you know it is, then you can parse it into a Timestamp like so:

use jiff::{fmt::strtime::BrokenDownTime, tz::Offset};

let mut tm = BrokenDownTime::parse(
    "%Y-%m-%d at %H:%M:%S",
    "1970-01-01 at 01:00:00",
)?;
tm.set_offset(Some(Offset::UTC));
// Normally this would fail since the parse
// itself doesn't include an offset. It only
// works here because we explicitly set the
// offset after parsing.
assert_eq!(tm.to_timestamp()?.to_string(), "1970-01-01T01:00:00Z");
§Example: setting the offset is not “smart”

This example shows how setting the offset on an existing broken down time does not impact any other field, even if the result printed is non-sensical:

use jiff::{civil::date, fmt::strtime::BrokenDownTime, tz};

let zdt = date(2024, 8, 28).at(14, 56, 0, 0).intz("US/Eastern")?;
let mut tm = BrokenDownTime::from(&zdt);
tm.set_offset(Some(tz::offset(12)));
assert_eq!(
    tm.to_string("%Y-%m-%d at %H:%M:%S in %V %:z")?,
    "2024-08-28 at 14:56:00 in US/Eastern +12:00",
);

pub fn set_iana_time_zone(&mut self, id: Option<String>)

Set the IANA time zone identifier on this broken down time.

This can be useful for setting the time zone after parsing if the time zone is known from the context or from some out-of-band information.

Note that one can set any string value, regardless of whether it’s consistent with the offset on this broken down time (if it’s set). Similarly, setting the IANA time zone identifier does not actually change any other value in this broken down time.

§Example: setting the IANA time zone identifier after parsing

One use case for this routine is when parsing a datetime without a time zone, but where one wants to set a time zone based on the context.

use jiff::{fmt::strtime::BrokenDownTime, tz::Offset};

let mut tm = BrokenDownTime::parse(
    "%Y-%m-%d at %H:%M:%S",
    "1970-01-01 at 01:00:00",
)?;
tm.set_iana_time_zone(Some(String::from("US/Eastern")));
// Normally this would fail since the parse
// itself doesn't include an offset or a time
// zone. It only works here because we
// explicitly set the time zone after parsing.
assert_eq!(
    tm.to_zoned()?.to_string(),
    "1970-01-01T01:00:00-05:00[US/Eastern]",
);
§Example: setting the IANA time zone identifier is not “smart”

This example shows how setting the IANA time zone identifier on an existing broken down time does not impact any other field, even if the result printed is non-sensical:

use jiff::{civil::date, fmt::strtime::BrokenDownTime, tz};

let zdt = date(2024, 8, 28).at(14, 56, 0, 0).intz("US/Eastern")?;
let mut tm = BrokenDownTime::from(&zdt);
tm.set_iana_time_zone(Some(String::from("Australia/Tasmania")));
assert_eq!(
    tm.to_string("%Y-%m-%d at %H:%M:%S in %V %:z")?,
    "2024-08-28 at 14:56:00 in Australia/Tasmania -04:00",
);

// In fact, it's not even required that the string
// given be a valid IANA time zone identifier!
let mut tm = BrokenDownTime::from(&zdt);
tm.set_iana_time_zone(Some(String::from("Clearly/Invalid")));
assert_eq!(
    tm.to_string("%Y-%m-%d at %H:%M:%S in %V %:z")?,
    "2024-08-28 at 14:56:00 in Clearly/Invalid -04:00",
);

pub fn set_weekday(&mut self, weekday: Option<Weekday>)

Set the weekday on this broken down time.

§Example
use jiff::{civil::Weekday, fmt::strtime::BrokenDownTime};

let mut tm = BrokenDownTime::default();
tm.set_weekday(Some(Weekday::Saturday));
assert_eq!(tm.to_string("%A")?, "Saturday");
assert_eq!(tm.to_string("%a")?, "Sat");
assert_eq!(tm.to_string("%^a")?, "SAT");

Note that one use case for this routine is to enable parsing of weekdays in datetime, but skip checking that the weekday is valid for the parsed date.

use jiff::{civil::date, fmt::strtime::BrokenDownTime};

let mut tm = BrokenDownTime::parse("%a, %F", "Wed, 2024-07-27")?;
// 2024-07-27 was a Saturday, so asking for a date fails:
assert!(tm.to_date().is_err());
// But we can remove the weekday from our broken down time:
tm.set_weekday(None);
assert_eq!(tm.to_date()?, date(2024, 7, 27));

The advantage of this approach is that it still ensures the parsed weekday is a valid weekday (for example, Wat will cause parsing to fail), but doesn’t require it to be consistent with the date. This is useful for interacting with systems that don’t do strict error checking.

Trait Implementations§

§

impl Debug for BrokenDownTime

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for BrokenDownTime

§

fn default() -> BrokenDownTime

Returns the “default value” for a type. Read more
§

impl<'a> From<&'a Zoned> for BrokenDownTime

§

fn from(zdt: &'a Zoned) -> BrokenDownTime

Converts to this type from the input type.
§

impl From<Date> for BrokenDownTime

§

fn from(d: Date) -> BrokenDownTime

Converts to this type from the input type.
§

impl From<DateTime> for BrokenDownTime

§

fn from(dt: DateTime) -> BrokenDownTime

Converts to this type from the input type.
§

impl From<Time> for BrokenDownTime

§

fn from(t: Time) -> BrokenDownTime

Converts to this type from the input type.
§

impl From<Timestamp> for BrokenDownTime

§

fn from(ts: Timestamp) -> BrokenDownTime

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> ArchivePointee for T

§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByteSized for T

Source§

const BYTE_ALIGN: usize = _

The alignment of this type in bytes.
Source§

const BYTE_SIZE: usize = _

The size of this type in bytes.
Source§

fn byte_align(&self) -> usize

Returns the alignment of this type in bytes.
Source§

fn byte_size(&self) -> usize

Returns the size of this type in bytes. Read more
Source§

fn ptr_size_ratio(&self) -> [usize; 2]

Returns the size ratio between Ptr::BYTES and BYTE_SIZE. Read more
Source§

impl<T, R> Chain<R> for T
where T: ?Sized,

Source§

fn chain<F>(self, f: F) -> R
where F: FnOnce(Self) -> R, Self: Sized,

Chain a function which takes the parameter by value.
Source§

fn chain_ref<F>(&self, f: F) -> R
where F: FnOnce(&Self) -> R,

Chain a function which takes the parameter by shared reference.
Source§

fn chain_mut<F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self) -> R,

Chain a function which takes the parameter by exclusive reference.
Source§

impl<T> ExtAny for T
where T: Any + ?Sized,

Source§

fn type_id() -> TypeId

Returns the TypeId of Self. Read more
Source§

fn type_of(&self) -> TypeId

Returns the TypeId of self. Read more
Source§

fn type_name(&self) -> &'static str

Returns the type name of self. Read more
Source§

fn type_is<T: 'static>(&self) -> bool

Returns true if Self is of type T. Read more
Source§

fn as_any_ref(&self) -> &dyn Any
where Self: Sized,

Upcasts &self as &dyn Any. Read more
Source§

fn as_any_mut(&mut self) -> &mut dyn Any
where Self: Sized,

Upcasts &mut self as &mut dyn Any. Read more
Source§

fn as_any_box(self: Box<Self>) -> Box<dyn Any>
where Self: Sized,

Upcasts Box<self> as Box<dyn Any>. Read more
Source§

fn downcast_ref<T: 'static>(&self) -> Option<&T>

Available on crate feature unsafe_layout only.
Returns some shared reference to the inner value if it is of type T. Read more
Source§

fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T>

Available on crate feature unsafe_layout only.
Returns some exclusive reference to the inner value if it is of type T. Read more
Source§

impl<T> ExtMem for T
where T: ?Sized,

Source§

const NEEDS_DROP: bool = _

Know whether dropping values of this type matters, in compile-time.
Source§

fn mem_align_of<T>() -> usize

Returns the minimum alignment of the type in bytes. Read more
Source§

fn mem_align_of_val(&self) -> usize

Returns the alignment of the pointed-to value in bytes. Read more
Source§

fn mem_size_of<T>() -> usize

Returns the size of a type in bytes. Read more
Source§

fn mem_size_of_val(&self) -> usize

Returns the size of the pointed-to value in bytes. Read more
Source§

fn mem_copy(&self) -> Self
where Self: Copy,

Bitwise-copies a value. Read more
Source§

fn mem_needs_drop(&self) -> bool

Returns true if dropping values of this type matters. Read more
Source§

fn mem_drop(self)
where Self: Sized,

Drops self by running its destructor. Read more
Source§

fn mem_forget(self)
where Self: Sized,

Forgets about self without running its destructor. Read more
Source§

fn mem_replace(&mut self, other: Self) -> Self
where Self: Sized,

Replaces self with other, returning the previous value of self. Read more
Source§

fn mem_take(&mut self) -> Self
where Self: Default,

Replaces self with its default value, returning the previous value of self. Read more
Source§

fn mem_swap(&mut self, other: &mut Self)
where Self: Sized,

Swaps the value of self and other without deinitializing either one. Read more
Source§

unsafe fn mem_zeroed<T>() -> T

Available on crate feature unsafe_layout only.
Returns the value of type T represented by the all-zero byte-pattern. Read more
Source§

unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst

Available on crate feature unsafe_layout only.
Returns the value of type T represented by the all-zero byte-pattern. Read more
Source§

fn mem_as_bytes(&self) -> &[u8]
where Self: Sync + Unpin,

Available on crate feature unsafe_slice only.
View a Sync + Unpin self as &[u8]. Read more
Source§

fn mem_as_bytes_mut(&mut self) -> &mut [u8]
where Self: Sync + Unpin,

Available on crate feature unsafe_slice only.
View a Sync + Unpin self as &mut [u8]. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

Source§

impl<T> Hook for T

Source§

fn hook_ref<F>(self, f: F) -> Self
where F: FnOnce(&Self),

Applies a function which takes the parameter by shared reference, and then returns the (possibly) modified owned value. Read more
Source§

fn hook_mut<F>(self, f: F) -> Self
where F: FnOnce(&mut Self),

Applies a function which takes the parameter by exclusive reference, and then returns the (possibly) modified owned value. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> LayoutRaw for T

§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Pointee for T

§

type Metadata = ()

The metadata type for pointers and references to this type.
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> Ungil for T
where T: Send,