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