rustmax::jiff::fmt::strtime

Struct BrokenDownTime

Source
pub struct BrokenDownTime { /* private fields */ }
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§

Source§

impl BrokenDownTime

Source

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));
Source

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

Parse a prefix of the given input according to the given format string. The offset returned corresponds to the number of bytes parsed. That is, the length of the prefix (which may be the length of the entire input if there are no unparsed bytes remaining).

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

This is like BrokenDownTime::parse, but it won’t return an error if there is input remaining after parsing the format directives.

§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};

// %y only parses two-digit years, so the 99 following
// 24 is unparsed!
let input = "7/14/2499";
let (tm, offset) = BrokenDownTime::parse_prefix("%m/%d/%y", input)?;
let date = tm.to_date()?;
assert_eq!(date, civil::date(2024, 7, 14));
assert_eq!(offset, 7);
assert_eq!(&input[offset..], "99");

If the entire input is parsed, then the offset is the length of the input:

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

let (tm, offset) = BrokenDownTime::parse_prefix(
    "%m/%d/%y", "7/14/24",
)?;
let date = tm.to_date()?;
assert_eq!(date, civil::date(2024, 7, 14));
assert_eq!(offset, 7);
§Example: how to parse a only parse of a timestamp

If you only need, for example, the date from a timestamp, then you can parse it as a prefix:

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

let input = "2024-01-20T17:55Z";
let (tm, offset) = BrokenDownTime::parse_prefix("%Y-%m-%d", input)?;
let date = tm.to_date()?;
assert_eq!(date, civil::date(2024, 1, 20));
assert_eq!(offset, 10);
assert_eq!(&input[offset..], "T17:55Z");

Note though that Jiff’s default parsing functions are already quite flexible, and one can just parse a civil date directly from a timestamp automatically:

use jiff::civil;

let input = "2024-01-20T17:55-05";
let date: civil::Date = input.parse()?;
assert_eq!(date, civil::date(2024, 1, 20));

Although in this case, you don’t get the length of the prefix parsed.

Source

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).in_tz("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");
Source

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).in_tz("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");
Source

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 %Q 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 %Q 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 %:Q",
    "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 %:Q",
    "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",
);
Source

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 %Q 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 %Q 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 %:Q",
    "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]");
Source

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");
Source

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");
Source

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

Extracts a civil date from this broken down time.

This requires that the year is set along with a way to identify the day in the year. This can be done by either setting the month and the day of the month (%m and %d), or by setting the day of the year (%j).

§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 and either the month and day or the day of the year.

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");
Source

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");
Source

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());
Source

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));
Source

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());
Source

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

Returns the parsed day of the year (1-366), if available.

§Example

This shows how to parse the day of the year:

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

let tm = BrokenDownTime::parse("%j", "5")?;
assert_eq!(tm.day_of_year(), Some(5));
assert_eq!(tm.to_string("%j")?, "005");
assert_eq!(tm.to_string("%-j")?, "5");

// Parsing the day of the year works for all possible legal
// values, even if, e.g., 366 isn't valid for all possible
// year/month combinations.
let tm = BrokenDownTime::parse("%j", "366")?;
assert_eq!(tm.day_of_year(), Some(366));
// This is true even if you're parsing a year:
let tm = BrokenDownTime::parse("%Y/%j", "2023/366")?;
assert_eq!(tm.day_of_year(), Some(366));
// An error only occurs when you try to extract a date:
assert_eq!(
    tm.to_date().unwrap_err().to_string(),
    "invalid date: parameter 'day-of-year' with value 366 \
     is not in the required range of 1..=365",
);
// But parsing a value that is always illegal will
// result in an error:
assert!(BrokenDownTime::parse("%j", "0").is_err());
assert!(BrokenDownTime::parse("%j", "367").is_err());
§Example: extract a Date

This example shows how parsing a year and a day of the year enables the extraction of a date:

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

let tm = BrokenDownTime::parse("%Y-%j", "2024-60")?;
assert_eq!(tm.to_date()?, date(2024, 2, 29));

When all of %m, %d and %j are used, then %m and %d take priority over %j when extracting a Date from a BrokenDownTime. However, %j is still parsed and accessible:

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

let tm = BrokenDownTime::parse(
    "%Y-%m-%d (day of year: %j)",
    "2024-02-29 (day of year: 1)",
)?;
assert_eq!(tm.to_date()?, date(2024, 2, 29));
assert_eq!(tm.day_of_year(), Some(1));
Source

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

Returns the parsed ISO 8601 week-based year, if available.

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

§Example

This shows how to parse just an ISO 8601 week-based year:

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

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

And 2-digit years are supported too:

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

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

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

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

Returns the parsed ISO 8601 week-based number, if available.

The week number is guaranteed to be in the range 1..53. Week 1 is the first week of the year to contain 4 days.

§Example

This shows how to parse just an ISO 8601 week-based dates:

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

let tm = BrokenDownTime::parse("%G-W%V-%w", "2020-W01-1")?;
assert_eq!(tm.iso_week_year(), Some(2020));
assert_eq!(tm.iso_week(), Some(1));
assert_eq!(tm.weekday(), Some(Weekday::Monday));
assert_eq!(tm.to_date()?, date(2019, 12, 30));
Source

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

Returns the Sunday based week number.

The week number returned is always in the range 0..=53. Week 1 begins on the first Sunday of the year. Any days in the year prior to week 1 are in week 0.

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

let tm = BrokenDownTime::parse("%Y-%U-%w", "2025-01-0")?;
assert_eq!(tm.year(), Some(2025));
assert_eq!(tm.sunday_based_week(), Some(1));
assert_eq!(tm.weekday(), Some(Weekday::Sunday));
assert_eq!(tm.to_date()?, date(2025, 1, 5));
Source

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

Returns the Monday based week number.

The week number returned is always in the range 0..=53. Week 1 begins on the first Monday of the year. Any days in the year prior to week 1 are in week 0.

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

let tm = BrokenDownTime::parse("%Y-%U-%w", "2025-01-1")?;
assert_eq!(tm.year(), Some(2025));
assert_eq!(tm.sunday_based_week(), Some(1));
assert_eq!(tm.weekday(), Some(Weekday::Monday));
assert_eq!(tm.to_date()?, date(2025, 1, 6));
Source

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));
Source

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));
Source

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));
Source

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));
Source

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()),
);
Source

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("%Q", "US/Eastern")?;
assert_eq!(tm.iana_time_zone(), Some("US/Eastern"));
assert_eq!(tm.offset(), None);

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

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));
Source

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));
Source

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");
Source

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");
Source

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");
Source

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

Set the day of year 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, month and day-of-month components already set.

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

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_day_of_year(Some(367)).is_err());
tm.set_day_of_year(Some(31))?;
assert_eq!(tm.to_string("%j")?, "031");

// Works even if the resulting date is invalid.
let mut tm = BrokenDownTime::default();
tm.set_year(Some(2023))?;
tm.set_day_of_year(Some(366))?; // 2023 wasn't a leap year
assert_eq!(tm.to_string("%Y/%j")?, "2023/366");
Source

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

Set the ISO 8601 week-based 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_iso_week_year(Some(10_000)).is_err());
tm.set_iso_week_year(Some(2024))?;
assert_eq!(tm.to_string("%G")?, "2024");
Source

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

Set the ISO 8601 week-based number on this broken down time.

The week number must be in the range 1..53. Week 1 is the first week of the year to contain 4 days.

§Errors

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

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

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_iso_week(Some(0)).is_err());
// out of range
assert!(tm.set_iso_week(Some(54)).is_err());

tm.set_iso_week_year(Some(2020))?;
tm.set_iso_week(Some(1))?;
tm.set_weekday(Some(Weekday::Monday));
assert_eq!(tm.to_string("%G-W%V-%w")?, "2020-W01-1");
assert_eq!(tm.to_string("%F")?, "2019-12-30");
Source

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

Set the Sunday based week number.

The week number returned is always in the range 0..=53. Week 1 begins on the first Sunday of the year. Any days in the year prior to week 1 are in week 0.

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

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_sunday_based_week(Some(56)).is_err());
tm.set_sunday_based_week(Some(9))?;
assert_eq!(tm.to_string("%U")?, "09");
Source

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

Set the Monday based week number.

The week number returned is always in the range 0..=53. Week 1 begins on the first Monday of the year. Any days in the year prior to week 1 are in week 0.

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

let mut tm = BrokenDownTime::default();
// out of range
assert!(tm.set_monday_based_week(Some(56)).is_err());
tm.set_monday_based_week(Some(9))?;
assert_eq!(tm.to_string("%W")?, "09");
Source

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");
Source

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");
Source

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");
Source

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");
Source

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).in_tz("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 %Q %:z")?,
    "2024-08-28 at 14:56:00 in US/Eastern +12:00",
);
Source

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).in_tz("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 %Q %: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 %Q %:z")?,
    "2024-08-28 at 14:56:00 in Clearly/Invalid -04:00",
);
Source

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§

Source§

impl Debug for BrokenDownTime

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for BrokenDownTime

Source§

fn default() -> BrokenDownTime

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

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

Source§

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

Converts to this type from the input type.
Source§

impl From<Date> for BrokenDownTime

Source§

fn from(d: Date) -> BrokenDownTime

Converts to this type from the input type.
Source§

impl From<DateTime> for BrokenDownTime

Source§

fn from(dt: DateTime) -> BrokenDownTime

Converts to this type from the input type.
Source§

impl From<ISOWeekDate> for BrokenDownTime

Source§

fn from(wd: ISOWeekDate) -> BrokenDownTime

Converts to this type from the input type.
Source§

impl From<Time> for BrokenDownTime

Source§

fn from(t: Time) -> BrokenDownTime

Converts to this type from the input type.
Source§

impl From<Timestamp> for BrokenDownTime

Source§

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
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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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

impl<T> Pointable for T

Source§

const ALIGN: usize = _

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

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

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T