Skip to content

Commit 30735ee

Browse files
committed
Make DelayedFormat hold a generic offset
1 parent 0cfc405 commit 30735ee

File tree

3 files changed

+84
-50
lines changed

3 files changed

+84
-50
lines changed

src/date.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ where
334334
#[cfg(feature = "alloc")]
335335
#[inline]
336336
#[must_use]
337-
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
337+
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I, Tz::Offset>
338338
where
339339
I: Iterator<Item = B> + Clone,
340340
B: Borrow<Item<'a>>,
@@ -348,7 +348,7 @@ where
348348
#[cfg(feature = "alloc")]
349349
#[inline]
350350
#[must_use]
351-
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
351+
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>, Tz::Offset> {
352352
self.format_with_items(StrftimeItems::new(fmt))
353353
}
354354

@@ -360,7 +360,7 @@ where
360360
&self,
361361
items: I,
362362
locale: Locale,
363-
) -> DelayedFormat<I>
363+
) -> DelayedFormat<I, Tz::Offset>
364364
where
365365
I: Iterator<Item = B> + Clone,
366366
B: Borrow<Item<'a>>,
@@ -384,7 +384,7 @@ where
384384
&self,
385385
fmt: &'a str,
386386
locale: Locale,
387-
) -> DelayedFormat<StrftimeItems<'a>> {
387+
) -> DelayedFormat<StrftimeItems<'a>, Tz::Offset> {
388388
self.format_localized_with_items(StrftimeItems::new_with_locale(fmt, locale), locale)
389389
}
390390
}

src/datetime/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ where
11011101
#[cfg(feature = "alloc")]
11021102
#[inline]
11031103
#[must_use]
1104-
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
1104+
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I, Tz::Offset>
11051105
where
11061106
I: Iterator<Item = B> + Clone,
11071107
B: Borrow<Item<'a>>,
@@ -1125,7 +1125,7 @@ where
11251125
#[cfg(feature = "alloc")]
11261126
#[inline]
11271127
#[must_use]
1128-
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
1128+
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>, Tz::Offset> {
11291129
self.format_with_items(StrftimeItems::new(fmt))
11301130
}
11311131

@@ -1137,7 +1137,7 @@ where
11371137
&self,
11381138
items: I,
11391139
locale: Locale,
1140-
) -> DelayedFormat<I>
1140+
) -> DelayedFormat<I, Tz::Offset>
11411141
where
11421142
I: Iterator<Item = B> + Clone,
11431143
B: Borrow<Item<'a>>,
@@ -1164,7 +1164,7 @@ where
11641164
&self,
11651165
fmt: &'a str,
11661166
locale: Locale,
1167-
) -> DelayedFormat<StrftimeItems<'a>> {
1167+
) -> DelayedFormat<StrftimeItems<'a>, Tz::Offset> {
11681168
self.format_localized_with_items(StrftimeItems::new_with_locale(fmt, locale), locale)
11691169
}
11701170
}

src/format/formatting.rs

Lines changed: 76 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! Date and time formatting routines.
55
66
#[cfg(all(feature = "alloc", not(feature = "std"), not(test)))]
7-
use alloc::string::{String, ToString};
7+
use alloc::string::String;
88
#[cfg(feature = "alloc")]
99
use core::borrow::Borrow;
1010
#[cfg(feature = "alloc")]
@@ -16,7 +16,7 @@ use crate::offset::Offset;
1616
#[cfg(any(feature = "alloc", feature = "serde"))]
1717
use crate::{Datelike, FixedOffset, NaiveDateTime, Timelike};
1818
#[cfg(feature = "alloc")]
19-
use crate::{NaiveDate, NaiveTime, Weekday};
19+
use crate::{NaiveDate, NaiveTime, Utc, Weekday};
2020

2121
#[cfg(feature = "alloc")]
2222
use super::locales;
@@ -31,13 +31,13 @@ use locales::*;
3131
/// This is normally constructed via `format` methods of each date and time type.
3232
#[cfg(feature = "alloc")]
3333
#[derive(Debug)]
34-
pub struct DelayedFormat<I> {
34+
pub struct DelayedFormat<I, Off = Utc> {
3535
/// The date view, if any.
3636
date: Option<NaiveDate>,
3737
/// The time view, if any.
3838
time: Option<NaiveTime>,
39-
/// The name and local-to-UTC difference for the offset (timezone), if any.
40-
off: Option<(String, FixedOffset)>,
39+
/// The offset from UTC, if any
40+
off: Option<Off>,
4141
/// An iterator returning formatting items.
4242
items: I,
4343
/// Locale used for text.
@@ -46,28 +46,17 @@ pub struct DelayedFormat<I> {
4646
}
4747

4848
#[cfg(feature = "alloc")]
49-
impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
49+
impl<'a, I, B> DelayedFormat<I>
50+
where
51+
I: Iterator<Item = B> + Clone,
52+
B: Borrow<Item<'a>>,
53+
{
5054
/// Makes a new `DelayedFormat` value out of local date and time.
5155
#[must_use]
5256
pub fn new(date: Option<NaiveDate>, time: Option<NaiveTime>, items: I) -> DelayedFormat<I> {
5357
DelayedFormat { date, time, off: None, items, locale: default_locale() }
5458
}
5559

56-
/// Makes a new `DelayedFormat` value out of local date and time and UTC offset.
57-
#[must_use]
58-
pub fn new_with_offset<Off>(
59-
date: Option<NaiveDate>,
60-
time: Option<NaiveTime>,
61-
offset: &Off,
62-
items: I,
63-
) -> DelayedFormat<I>
64-
where
65-
Off: Offset + Display,
66-
{
67-
let name_and_diff = (offset.to_string(), offset.fix());
68-
DelayedFormat { date, time, off: Some(name_and_diff), items, locale: default_locale() }
69-
}
70-
7160
/// Makes a new `DelayedFormat` value out of local date and time and locale.
7261
#[cfg(feature = "unstable-locales")]
7362
#[must_use]
@@ -79,22 +68,40 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
7968
) -> DelayedFormat<I> {
8069
DelayedFormat { date, time, off: None, items, locale }
8170
}
71+
}
72+
73+
#[cfg(feature = "alloc")]
74+
impl<'a, I, B, Off> DelayedFormat<I, Off>
75+
where
76+
I: Iterator<Item = B> + Clone,
77+
B: Borrow<Item<'a>>,
78+
Off: Offset + Display,
79+
{
80+
/// Makes a new `DelayedFormat` value out of local date and time and UTC offset.
81+
#[must_use]
82+
pub fn new_with_offset(
83+
date: Option<NaiveDate>,
84+
time: Option<NaiveTime>,
85+
offset: &Off,
86+
items: I,
87+
) -> DelayedFormat<I, Off> {
88+
DelayedFormat { date, time, off: Some(offset.clone()), items, locale: default_locale() }
89+
}
8290

8391
/// Makes a new `DelayedFormat` value out of local date and time, UTC offset and locale.
8492
#[cfg(feature = "unstable-locales")]
8593
#[must_use]
86-
pub fn new_with_offset_and_locale<Off>(
94+
pub fn new_with_offset_and_locale(
8795
date: Option<NaiveDate>,
8896
time: Option<NaiveTime>,
8997
offset: &Off,
9098
items: I,
9199
locale: Locale,
92-
) -> DelayedFormat<I>
100+
) -> DelayedFormat<I, Off>
93101
where
94102
Off: Offset + Display,
95103
{
96-
let name_and_diff = (offset.to_string(), offset.fix());
97-
DelayedFormat { date, time, off: Some(name_and_diff), items, locale }
104+
DelayedFormat { date, time, off: Some(offset.clone()), items, locale }
98105
}
99106

100107
fn format(&self, w: &mut impl Write) -> fmt::Result {
@@ -191,7 +198,7 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
191198
write_n(w, 9, (t.nanosecond() % 1_000_000_000) as i64, pad, false)
192199
}
193200
(Timestamp, Some(d), Some(t)) => {
194-
let offset = self.off.as_ref().map(|(_, o)| i64::from(o.local_minus_utc()));
201+
let offset = self.off.as_ref().map(|o| i64::from(o.fix().local_minus_utc()));
195202
let timestamp = d.and_time(t).and_utc().timestamp() - offset.unwrap_or(0);
196203
write_n(w, 9, timestamp, pad, false)
197204
}
@@ -265,50 +272,50 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
265272
(Internal(InternalFixed { val: Nanosecond9NoDot }), _, Some(t), _) => {
266273
write!(w, "{:09}", t.nanosecond() % 1_000_000_000)
267274
}
268-
(TimezoneName, _, _, Some((tz_name, _))) => write!(w, "{}", tz_name),
269-
(TimezoneOffset | TimezoneOffsetZ, _, _, Some((_, off))) => {
275+
(TimezoneName, _, _, Some(off)) => write!(w, "{}", off),
276+
(TimezoneOffset | TimezoneOffsetZ, _, _, Some(off)) => {
270277
let offset_format = OffsetFormat {
271278
precision: OffsetPrecision::Minutes,
272279
colons: Colons::Maybe,
273280
allow_zulu: *spec == TimezoneOffsetZ,
274281
padding: Pad::Zero,
275282
};
276-
offset_format.format(w, *off)
283+
offset_format.format(w, off.fix())
277284
}
278-
(TimezoneOffsetColon | TimezoneOffsetColonZ, _, _, Some((_, off))) => {
285+
(TimezoneOffsetColon | TimezoneOffsetColonZ, _, _, Some(off)) => {
279286
let offset_format = OffsetFormat {
280287
precision: OffsetPrecision::Minutes,
281288
colons: Colons::Colon,
282289
allow_zulu: *spec == TimezoneOffsetColonZ,
283290
padding: Pad::Zero,
284291
};
285-
offset_format.format(w, *off)
292+
offset_format.format(w, off.fix())
286293
}
287-
(TimezoneOffsetDoubleColon, _, _, Some((_, off))) => {
294+
(TimezoneOffsetDoubleColon, _, _, Some(off)) => {
288295
let offset_format = OffsetFormat {
289296
precision: OffsetPrecision::Seconds,
290297
colons: Colons::Colon,
291298
allow_zulu: false,
292299
padding: Pad::Zero,
293300
};
294-
offset_format.format(w, *off)
301+
offset_format.format(w, off.fix())
295302
}
296-
(TimezoneOffsetTripleColon, _, _, Some((_, off))) => {
303+
(TimezoneOffsetTripleColon, _, _, Some(off)) => {
297304
let offset_format = OffsetFormat {
298305
precision: OffsetPrecision::Hours,
299306
colons: Colons::None,
300307
allow_zulu: false,
301308
padding: Pad::Zero,
302309
};
303-
offset_format.format(w, *off)
310+
offset_format.format(w, off.fix())
304311
}
305-
(RFC2822, Some(d), Some(t), Some((_, off))) => {
306-
write_rfc2822(w, crate::NaiveDateTime::new(d, t), *off)
312+
(RFC2822, Some(d), Some(t), Some(off)) => {
313+
write_rfc2822(w, crate::NaiveDateTime::new(d, t), off.fix())
307314
}
308-
(RFC3339, Some(d), Some(t), Some((_, off))) => write_rfc3339(
315+
(RFC3339, Some(d), Some(t), Some(off)) => write_rfc3339(
309316
w,
310317
crate::NaiveDateTime::new(d, t),
311-
*off,
318+
off.fix(),
312319
SecondsFormat::AutoSi,
313320
false,
314321
),
@@ -318,7 +325,12 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
318325
}
319326

320327
#[cfg(feature = "alloc")]
321-
impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> Display for DelayedFormat<I> {
328+
impl<'a, I, B, Off> Display for DelayedFormat<I, Off>
329+
where
330+
I: Iterator<Item = B> + Clone,
331+
B: Borrow<Item<'a>>,
332+
Off: Offset + Display,
333+
{
322334
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
323335
let mut result = String::new();
324336
self.format(&mut result)?;
@@ -344,7 +356,7 @@ where
344356
DelayedFormat {
345357
date: date.copied(),
346358
time: time.copied(),
347-
off: off.cloned(),
359+
off: off.cloned().map(|(tz_name, offset)| OffsetWrapper { offset, tz_name }),
348360
items,
349361
locale: default_locale(),
350362
}
@@ -364,13 +376,35 @@ pub fn format_item(
364376
DelayedFormat {
365377
date: date.copied(),
366378
time: time.copied(),
367-
off: off.cloned(),
379+
off: off.cloned().map(|(tz_name, offset)| OffsetWrapper { offset, tz_name }),
368380
items: [item].into_iter(),
369381
locale: default_locale(),
370382
}
371383
.fmt(w)
372384
}
373385

386+
/// Only used by the deprecated `format` and `format_item` functions.
387+
#[cfg(feature = "alloc")]
388+
#[derive(Clone, Debug)]
389+
struct OffsetWrapper {
390+
offset: FixedOffset,
391+
tz_name: String,
392+
}
393+
394+
#[cfg(feature = "alloc")]
395+
impl Offset for OffsetWrapper {
396+
fn fix(&self) -> FixedOffset {
397+
self.offset
398+
}
399+
}
400+
401+
#[cfg(feature = "alloc")]
402+
impl Display for OffsetWrapper {
403+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
404+
f.write_str(&self.tz_name)
405+
}
406+
}
407+
374408
#[cfg(any(feature = "alloc", feature = "serde"))]
375409
impl OffsetFormat {
376410
/// Writes an offset from UTC with the format defined by `self`.

0 commit comments

Comments
 (0)