]> git.proxmox.com Git - rustc.git/blob - vendor/time-0.1.43/src/display.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / vendor / time-0.1.43 / src / display.rs
1 use std::fmt::{self, Write};
2
3 use super::{TmFmt, Tm, Fmt};
4
5 impl<'a> fmt::Display for TmFmt<'a> {
6 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
7 match self.format {
8 Fmt::Str(ref s) => {
9 let mut chars = s.chars();
10 while let Some(ch) = chars.next() {
11 if ch == '%' {
12 // we've already validated that % always precedes
13 // another char
14 parse_type(fmt, chars.next().unwrap(), self.tm)?;
15 } else {
16 fmt.write_char(ch)?;
17 }
18 }
19
20 Ok(())
21 }
22 Fmt::Ctime => self.tm.to_local().asctime().fmt(fmt),
23 Fmt::Rfc3339 => {
24 if self.tm.tm_utcoff == 0 {
25 TmFmt {
26 tm: self.tm,
27 format: Fmt::Str("%Y-%m-%dT%H:%M:%SZ"),
28 }.fmt(fmt)
29 } else {
30 let s = TmFmt {
31 tm: self.tm,
32 format: Fmt::Str("%Y-%m-%dT%H:%M:%S"),
33 };
34 let sign = if self.tm.tm_utcoff > 0 { '+' } else { '-' };
35 let mut m = abs(self.tm.tm_utcoff) / 60;
36 let h = m / 60;
37 m -= h * 60;
38 write!(fmt, "{}{}{:02}:{:02}", s, sign, h, m)
39 }
40 }
41 }
42 }
43 }
44
45 fn is_leap_year(year: i32) -> bool {
46 (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))
47 }
48
49 fn days_in_year(year: i32) -> i32 {
50 if is_leap_year(year) { 366 }
51 else { 365 }
52 }
53
54 fn iso_week_days(yday: i32, wday: i32) -> i32 {
55 /* The number of days from the first day of the first ISO week of this
56 * year to the year day YDAY with week day WDAY.
57 * ISO weeks start on Monday. The first ISO week has the year's first
58 * Thursday.
59 * YDAY may be as small as yday_minimum.
60 */
61 let iso_week_start_wday: i32 = 1; /* Monday */
62 let iso_week1_wday: i32 = 4; /* Thursday */
63 let yday_minimum: i32 = 366;
64 /* Add enough to the first operand of % to make it nonnegative. */
65 let big_enough_multiple_of_7: i32 = (yday_minimum / 7 + 2) * 7;
66
67 yday - (yday - wday + iso_week1_wday + big_enough_multiple_of_7) % 7
68 + iso_week1_wday - iso_week_start_wday
69 }
70
71 fn iso_week(fmt: &mut fmt::Formatter, ch:char, tm: &Tm) -> fmt::Result {
72 let mut year = tm.tm_year + 1900;
73 let mut days = iso_week_days(tm.tm_yday, tm.tm_wday);
74
75 if days < 0 {
76 /* This ISO week belongs to the previous year. */
77 year -= 1;
78 days = iso_week_days(tm.tm_yday + (days_in_year(year)), tm.tm_wday);
79 } else {
80 let d = iso_week_days(tm.tm_yday - (days_in_year(year)),
81 tm.tm_wday);
82 if 0 <= d {
83 /* This ISO week belongs to the next year. */
84 year += 1;
85 days = d;
86 }
87 }
88
89 match ch {
90 'G' => write!(fmt, "{}", year),
91 'g' => write!(fmt, "{:02}", (year % 100 + 100) % 100),
92 'V' => write!(fmt, "{:02}", days / 7 + 1),
93 _ => Ok(())
94 }
95 }
96
97 fn parse_type(fmt: &mut fmt::Formatter, ch: char, tm: &Tm) -> fmt::Result {
98 match ch {
99 'A' => fmt.write_str(match tm.tm_wday {
100 0 => "Sunday",
101 1 => "Monday",
102 2 => "Tuesday",
103 3 => "Wednesday",
104 4 => "Thursday",
105 5 => "Friday",
106 6 => "Saturday",
107 _ => unreachable!(),
108 }),
109 'a' => fmt.write_str(match tm.tm_wday {
110 0 => "Sun",
111 1 => "Mon",
112 2 => "Tue",
113 3 => "Wed",
114 4 => "Thu",
115 5 => "Fri",
116 6 => "Sat",
117 _ => unreachable!(),
118 }),
119 'B' => fmt.write_str(match tm.tm_mon {
120 0 => "January",
121 1 => "February",
122 2 => "March",
123 3 => "April",
124 4 => "May",
125 5 => "June",
126 6 => "July",
127 7 => "August",
128 8 => "September",
129 9 => "October",
130 10 => "November",
131 11 => "December",
132 _ => unreachable!(),
133 }),
134 'b' | 'h' => fmt.write_str(match tm.tm_mon {
135 0 => "Jan",
136 1 => "Feb",
137 2 => "Mar",
138 3 => "Apr",
139 4 => "May",
140 5 => "Jun",
141 6 => "Jul",
142 7 => "Aug",
143 8 => "Sep",
144 9 => "Oct",
145 10 => "Nov",
146 11 => "Dec",
147 _ => unreachable!(),
148 }),
149 'C' => write!(fmt, "{:02}", (tm.tm_year + 1900) / 100),
150 'c' => {
151 parse_type(fmt, 'a', tm)?;
152 fmt.write_str(" ")?;
153 parse_type(fmt, 'b', tm)?;
154 fmt.write_str(" ")?;
155 parse_type(fmt, 'e', tm)?;
156 fmt.write_str(" ")?;
157 parse_type(fmt, 'T', tm)?;
158 fmt.write_str(" ")?;
159 parse_type(fmt, 'Y', tm)
160 }
161 'D' | 'x' => {
162 parse_type(fmt, 'm', tm)?;
163 fmt.write_str("/")?;
164 parse_type(fmt, 'd', tm)?;
165 fmt.write_str("/")?;
166 parse_type(fmt, 'y', tm)
167 }
168 'd' => write!(fmt, "{:02}", tm.tm_mday),
169 'e' => write!(fmt, "{:2}", tm.tm_mday),
170 'f' => write!(fmt, "{:09}", tm.tm_nsec),
171 'F' => {
172 parse_type(fmt, 'Y', tm)?;
173 fmt.write_str("-")?;
174 parse_type(fmt, 'm', tm)?;
175 fmt.write_str("-")?;
176 parse_type(fmt, 'd', tm)
177 }
178 'G' => iso_week(fmt, 'G', tm),
179 'g' => iso_week(fmt, 'g', tm),
180 'H' => write!(fmt, "{:02}", tm.tm_hour),
181 'I' => {
182 let mut h = tm.tm_hour;
183 if h == 0 { h = 12 }
184 if h > 12 { h -= 12 }
185 write!(fmt, "{:02}", h)
186 }
187 'j' => write!(fmt, "{:03}", tm.tm_yday + 1),
188 'k' => write!(fmt, "{:2}", tm.tm_hour),
189 'l' => {
190 let mut h = tm.tm_hour;
191 if h == 0 { h = 12 }
192 if h > 12 { h -= 12 }
193 write!(fmt, "{:2}", h)
194 }
195 'M' => write!(fmt, "{:02}", tm.tm_min),
196 'm' => write!(fmt, "{:02}", tm.tm_mon + 1),
197 'n' => fmt.write_str("\n"),
198 'P' => fmt.write_str(if tm.tm_hour < 12 { "am" } else { "pm" }),
199 'p' => fmt.write_str(if (tm.tm_hour) < 12 { "AM" } else { "PM" }),
200 'R' => {
201 parse_type(fmt, 'H', tm)?;
202 fmt.write_str(":")?;
203 parse_type(fmt, 'M', tm)
204 }
205 'r' => {
206 parse_type(fmt, 'I', tm)?;
207 fmt.write_str(":")?;
208 parse_type(fmt, 'M', tm)?;
209 fmt.write_str(":")?;
210 parse_type(fmt, 'S', tm)?;
211 fmt.write_str(" ")?;
212 parse_type(fmt, 'p', tm)
213 }
214 'S' => write!(fmt, "{:02}", tm.tm_sec),
215 's' => write!(fmt, "{}", tm.to_timespec().sec),
216 'T' | 'X' => {
217 parse_type(fmt, 'H', tm)?;
218 fmt.write_str(":")?;
219 parse_type(fmt, 'M', tm)?;
220 fmt.write_str(":")?;
221 parse_type(fmt, 'S', tm)
222 }
223 't' => fmt.write_str("\t"),
224 'U' => write!(fmt, "{:02}", (tm.tm_yday - tm.tm_wday + 7) / 7),
225 'u' => {
226 let i = tm.tm_wday;
227 write!(fmt, "{}", (if i == 0 { 7 } else { i }))
228 }
229 'V' => iso_week(fmt, 'V', tm),
230 'v' => {
231 parse_type(fmt, 'e', tm)?;
232 fmt.write_str("-")?;
233 parse_type(fmt, 'b', tm)?;
234 fmt.write_str("-")?;
235 parse_type(fmt, 'Y', tm)
236 }
237 'W' => {
238 write!(fmt, "{:02}", (tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7) / 7)
239 }
240 'w' => write!(fmt, "{}", tm.tm_wday),
241 'Y' => write!(fmt, "{}", tm.tm_year + 1900),
242 'y' => write!(fmt, "{:02}", (tm.tm_year + 1900) % 100),
243 // FIXME (#2350): support locale
244 'Z' => fmt.write_str(if tm.tm_utcoff == 0 { "UTC"} else { "" }),
245 'z' => {
246 let sign = if tm.tm_utcoff > 0 { '+' } else { '-' };
247 let mut m = abs(tm.tm_utcoff) / 60;
248 let h = m / 60;
249 m -= h * 60;
250 write!(fmt, "{}{:02}{:02}", sign, h, m)
251 }
252 '+' => write!(fmt, "{}", tm.rfc3339()),
253 '%' => fmt.write_str("%"),
254 _ => unreachable!(),
255 }
256 }
257
258 fn abs(i: i32) -> i32 {
259 if i < 0 {-i} else {i}
260 }