1use bstr::BString;
2
3use crate::{time::Sign, Time};
4
5impl Time {
7 pub fn to_bstring(&self) -> BString {
9 let mut buf = Vec::with_capacity(64);
10 self.write_to(&mut buf).expect("write to memory cannot fail");
11 buf.into()
12 }
13
14 pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> {
16 let mut itoa = itoa::Buffer::new();
17 out.write_all(itoa.format(self.seconds_since_unix_epoch).as_bytes())?;
18 out.write_all(b" ")?;
19 out.write_all(match self.sign {
20 Sign::Plus => b"+",
21 Sign::Minus => b"-",
22 })?;
23
24 const ZERO: &[u8; 1] = b"0";
25
26 const SECONDS_PER_HOUR: i32 = 60 * 60;
27 let offset = self.offset_in_seconds.abs();
28 let hours = offset / SECONDS_PER_HOUR;
29 assert!(hours < 25, "offset is more than a day: {hours}");
30 let minutes = (offset - (hours * SECONDS_PER_HOUR)) / 60;
31
32 if hours < 10 {
33 out.write_all(ZERO)?;
34 }
35 out.write_all(itoa.format(hours).as_bytes())?;
36
37 if minutes < 10 {
38 out.write_all(ZERO)?;
39 }
40 out.write_all(itoa.format(minutes).as_bytes()).map(|_| ())
41 }
42
43 pub fn size(&self) -> usize {
45 (if self.seconds_since_unix_epoch >= 1_000_000_000 {
48 10
49 } else if self.seconds_since_unix_epoch >= 100_000_000 {
50 9
51 } else if self.seconds_since_unix_epoch >= 10_000_000 {
52 8
53 } else if self.seconds_since_unix_epoch >= 1_000_000 {
54 7
55 } else if self.seconds_since_unix_epoch >= 100_000 {
56 6
57 } else if self.seconds_since_unix_epoch >= 10_000 {
58 5
59 } else if self.seconds_since_unix_epoch >= 1_000 {
60 4
61 } else if self.seconds_since_unix_epoch >= 100 {
62 3
63 } else if self.seconds_since_unix_epoch >= 10 {
64 2
65 } else {
66 1
67 }) + 2 + 2 + 2 }
69}