e pattern language is a simple sequence of conversion specifiers interspersed
by literals and arbitrary whitespace. This means that you sometimes need
delimiters or spaces between components. For example, this is fine:

```
use jiff::fmt::strtime;

let date = strtime::parse("%Y%m%d", "20240715")?.to_date()?;
assert_eq!(date.to_string(), "2024-07-15");
# Ok::<(), Box<dyn std::error::Error>>(())
```

But this is ambiguous (is the year `999` or `9990`?):

```
use jiff::fmt::strtime;

assert!(strtime::parse("%Y%m%d", "9990715").is_err());
```

In this case, since years greedily consume up to 4 digits by default, `9990`
is parsed as the year. And since months greedily consume up to 2 digits by
default, `71` is parsed as the month, which results in an invalid day. If you
expect your datetimes to always use 4 digits for the year, then it might be
okay to skip on the delimiters. For example, the year `999` could be written
with a leading zero:

```
use jiff::fmt::strtime;

let date = strtime::parse("%Y%m%d", "09990715")?.to_date()?;
assert_eq!(date.to_string(), "0999-07-15");
// Indeed, the leading zero is written by default when
// formatting, since years are padded out to 4 digits
// by default:
assert_eq!(date.strftime("%Y%m%d").to_string(), "09990715");

# Ok::<(), Box<dyn std::error::Error>>(())
```

The main advice here is that these APIs can come in handy for ad hoc tasks that
would otherwise be annoying to deal with. For example, I once wrote a tool to
extract data from an XML dump of my SMS messages, and one of the date formats
used was `Apr 1, 2022 20:46:15`. That doesn't correspond to any standard, and
while parsing it with a regex isn't that difficult, it's pretty annoying,
especially because of the English abbreviated month name. That's exactly the
kind of use case where this module shines.

If the formatting machinery in this module isn't flexible enough for your use
case and you don't control the format, it is recommended to write a bespoke
parser (possibly with regex). It is unlikely that the expressiveness of this
formatting machinery will be improved much. (Although it is plausible to add
new conversion specifiers.)

# Conversion specifications

This table lists the complete set of conversion specifiers supported in the
format. While most conversion specifiers are supported as is in both parsing
and formatting, there are some differences. Where differences occur, they are
noted in the table below.

When parsing, and whenever a conversion specifier matches an enumeration of
strings, the strings are matched without regard to ASCII case.

| Specifier | Example | Description |
| --------- | ------- | ----------- |
| `%%` | `%%` | A literal `%`. |
| `%A`, `%a` | `Sunday`, `Sun` | The full and abbreviated weekday, respectively. |
| `%B`, `%b`, `%h` | `June`, `Jun`, `Jun` | The full and abbreviated month name, respectively. |
| `%C` | `20` | The century of the year. No padding. |
| `%c` | `2024 M07 14, Sun 17:31:59` | The date and clock time via [`Custom`]. Supported when formatting only. |
| `%D` | `7/14/24` | Equivalent to `%m/%d/%y`. |
| `%d`, `%e` | `25`, ` 5` | The day of the month. `%d` is zero-padded, `%e` is space padded. |
| `%F` | `2024-07-14` | Equivalent to `%Y-%m-%d`. |
| `%f` | `000456` | Fractional seconds, up to nanosecond precision. |
| `%.f` | `.000456` | Optional fractional seconds, with dot, up to nanosecond precision. |
| `%G` | `2024` | An [ISO 8601 week-based] year. Zero padded to 4 digits. |
| `%g` | `24` | A two-digit [ISO 8601 week-based] year. Represents only 1969-2068. Zero padded. |
| `%H` | `23` | The hour in a 24 hour clock. Zero padded. |
| `%I` | `11` | The hour in a 12 hour clock. Zero padded. |
| `%j` | `060` | The day of the year. Range is `1..=366`. Zero padded to 3 digits. |
| `%k` | `15` | The hour in a 24 hour clock. Space padded. |
| `%l` | ` 3` | The hour in a 12 hour clock. Space padded. |
| `%M` | `04` | The minute. Zero padded. |
| `%m` | `01` | The month. Zero padded. |
| `%N` | `123456000` | Fractional seconds, up to nanosecond precision. Alias for `%9f`. |
| `%n` | `\n` | Formats as a newline character. Parses arbitrary whitespace. |
| `%P` | `am` | Whether the time is in the AM or PM, lowercase. |
| `%p` | `PM` | Whether the time is in the AM or PM, uppercase. |
| `%Q` | `America/New_York`, `+0530` | An IANA time zone identifier, or `%z` if one doesn't exist. |
| `%:Q` | `America/New_York`, `+05:30` | An IANA time zone identifier, or `%:z` if one doesn't exist. |
| `%q` | `4` | The quarter of the year. Supported when formatting only. |
| `%R` | `23:30` | Equivalent to `%H:%M`. |
| `%r` | `8:30:00 AM` | The 12-hour clock time via [`Custom`]. Supported when formatting only. |
| `%S` | `59` | The second. Zero padded. |
| `%s` | `1737396540` | A Unix timestamp, in seconds. |
| `%T` | `23:30:59` | Equivalent to `%H:%M:%S`. |
| `%t` | `\t` | Formats as a tab character. Parses arbitrary whitespace. |
| `%U` | `03` | Week number. Week 1 is the first week starting with a Sunday. Zero padded. |
| `%u` | `7` | The day of the week beginning with Monday at `1`. |
| `%V` | `05` | Week number in the [ISO 8601 week-based] calendar. Zero padded. |
| `%W` | `03` | Week number. Week 1 is the first week starting with a Monday. Zero padded. |
| `%w` | `0` | The day of the week beginning with Sunday at `0`. |
| `%X` | `17:31:59` | The clock time via [`Custom`]. Supported when formatting only. |
| `%x` | `2024 M07 14` | The date via [`Custom`]. Supported when formatting only. |
| `%Y` | `2024` | A full year, including century. Zero padded to 4 digits. |
| `%y` | `24` | A two-digit year. Represents only 1969-2068. Zero padded. |
| `%Z` | `EDT` | A time zone abbreviation. Supported when formatting only. |
| `%z` | `+0530` | A time zone offset in the format `[+-]HHMM[SS]`. |
| `%:z` | `+05:30` | A time zone offset in the format `[+-]HH:MM[:SS]`. |
| `%::z` | `+05:30:00` | A time zone offset in the format `[+-]HH:MM:SS`. |
| `%:::z` | `-04`, `+05:30` | A time zone offset in the format `[+-]HH:[MM[:SS]]`. |

When formatting, the following flags can be inserted immediately after the `%`
and before the directive:

* `_` - Pad a numeric result to the left with spaces.
* `-` - Do not pad a numeric result.
* `0` - Pad a numeric result to the left with zeros.
* `^` - Use alphabetic uppercase for all relevant strings.
* `#` - Swap the case of the result string. This is typically only useful with
`%p` or `%Z`, since they are the only conversion specifiers that emit strings
entirely in uppercase by default.

The above flags override the "default" settings of a specifier. For example,
`%_d` pads with spaces instead of zeros, and `%0e` pads with zeros instead of
spaces. The exceptions are the locale (`%c`, `%r`, `%X`, `%x`), and time zone
(`%z`, `%:z`) specifiers. They are unaffected by any flags.

Moreover, any number of decimal digits can be inserted after the (possibly
absent) flag and before the directive, so long as the parsed number is less
than 256. The number formed by these digits will correspond to the minimum
amount of padding (to the left). Note that padding is clamped to a maximum of
`20`.

The flags and padding amount above may be used when parsing as well. Most
settings are ignored during parsing except for padding. For example, if one
wanted to parse `003` as the day `3`, then one should use `%03d`. Otherwise, by
default, `%d` will only try to consume at most 2 digits.

The `%f` and `%.f` flags also support specifying the precision, up to
nanoseconds. For example, `%3f` and `%.3f` will both always print a fractional
second component to exactly 3 decimal places. When no precision is specified,
then `%f` will always emit at least one digit, even if it's zero. But `%.f`
will emit the empty string when the fractional component is zero. Otherwise, it
will include the leading `.`. For parsing, `%f` does not include the leading
dot, but `%.f` does. Note that all of the options above are still parsed for
`%f` and `%.f`, but they are all no-ops (except for the padding for `%f`, which
is instead interpreted as a precision setting). When using a precision setting,
truncation is used. If you need a different rounding mode, you should use
higher level APIs like [`Timestamp::round`] or [`Zoned::round`].

# Conditionally unsupported

Jiff does not support `%Q` or `%:Q` (IANA time zone identifier) when the
`alloc` crate feature is not enabled. This is because a time zone identifier
is variable width data. If you have a use case for this, please
[detail it in a new issue](https://github.com/BurntSushi/jiff/issues/new).

# Unsupported

The following things are currently unsupported:

* Parsing or formatting fractional seconds in the time time zone offset.
* The `%+` conversion specifier is not supported since there doesn't seem to
  be any consistent definition for it.
* With only Jiff, the `%c`, `%r`, `%X` and `%x` locale oriented specifiers
  use a default "unknown" locale via the [`DefaultCustom`] implementation
  of the [`Custom`] trait. An example of the default locale format for `%c`
  is `2024 M07 14, Sun 17:31:59`. One can either switch the POSIX locale
  via [`PosixCustom`] (e.g., `Sun Jul 14 17:31:59 2024`), or write your own
  implementation of [`Custom`] powered by [`icu`] and glued together with Jiff
  via [`jiff-icu`].
* The `E` and `O` locale modifiers are not supported.

[`strftime`]: https://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
[`strptime`]: https://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
[ISO 8601 week-based]: https://en.wikipedia.org/wiki/ISO_week_date
[`icu`]: https://docs.rs/icu
[`jiff-icu`]: https://docs.rs/jiff-icu
