1 //! Formatting helpers for a `UtcOffset`.
2
3 #![allow(non_snake_case)]
4
5 use crate::{
6 error,
7 format::{
8 parse::{try_consume_exact_digits, try_consume_first_match},
9 Padding, ParsedItems,
10 },
11 ParseResult, UtcOffset,
12 };
13 use core::fmt::{self, Formatter};
14
15 /// UTC offset
fmt_z(f: &mut Formatter<'_>, offset: UtcOffset) -> fmt::Result16 pub(crate) fn fmt_z(f: &mut Formatter<'_>, offset: UtcOffset) -> fmt::Result {
17 let offset = offset.as_duration();
18
19 write!(
20 f,
21 "{}{:02}{:02}",
22 if offset.is_negative() { '-' } else { '+' },
23 offset.whole_hours().abs(),
24 (offset.whole_minutes() - 60 * offset.whole_hours()).abs()
25 )
26 }
27
28 /// UTC offset
parse_z(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()>29 pub(crate) fn parse_z(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()> {
30 let sign = try_consume_first_match(s, [("+", 1), ("-", -1)].iter().cloned())
31 .ok_or(error::Parse::InvalidOffset)?;
32
33 let hours: i16 =
34 try_consume_exact_digits(s, 2, Padding::Zero).ok_or(error::Parse::InvalidOffset)?;
35
36 let minutes: i16 =
37 try_consume_exact_digits(s, 2, Padding::Zero).ok_or(error::Parse::InvalidOffset)?;
38
39 items.offset = UtcOffset::minutes(sign * (hours * 60 + minutes)).into();
40 Ok(())
41 }
42