@@ -16,7 +16,7 @@ use crate::offset::Offset;
1616#[ cfg( any( feature = "alloc" , feature = "serde" ) ) ]
1717use 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" ) ]
2222use 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,26 +46,31 @@ 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 , Off > DelayedFormat < I , Off >
50+ where
51+ I : Iterator < Item = B > + Clone ,
52+ B : Borrow < Item < ' a > > ,
53+ Off : Offset + Display ,
54+ {
5055 /// Makes a new `DelayedFormat` value out of local date and time.
5156 #[ must_use]
52- pub fn new ( date : Option < NaiveDate > , time : Option < NaiveTime > , items : I ) -> DelayedFormat < I > {
57+ pub fn new (
58+ date : Option < NaiveDate > ,
59+ time : Option < NaiveTime > ,
60+ items : I ,
61+ ) -> DelayedFormat < I , Off > {
5362 DelayedFormat { date, time, off : None , items, locale : default_locale ( ) }
5463 }
5564
5665 /// Makes a new `DelayedFormat` value out of local date and time and UTC offset.
5766 #[ must_use]
58- pub fn new_with_offset < Off > (
67+ pub fn new_with_offset (
5968 date : Option < NaiveDate > ,
6069 time : Option < NaiveTime > ,
6170 offset : & Off ,
6271 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 ( ) }
72+ ) -> DelayedFormat < I , Off > {
73+ DelayedFormat { date, time, off : Some ( offset. clone ( ) ) , items, locale : default_locale ( ) }
6974 }
7075
7176 /// Makes a new `DelayedFormat` value out of local date and time and locale.
@@ -76,25 +81,24 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
7681 time : Option < NaiveTime > ,
7782 items : I ,
7883 locale : Locale ,
79- ) -> DelayedFormat < I > {
84+ ) -> DelayedFormat < I , Off > {
8085 DelayedFormat { date, time, off : None , items, locale }
8186 }
8287
8388 /// Makes a new `DelayedFormat` value out of local date and time, UTC offset and locale.
8489 #[ cfg( feature = "unstable-locales" ) ]
8590 #[ must_use]
86- pub fn new_with_offset_and_locale < Off > (
91+ pub fn new_with_offset_and_locale (
8792 date : Option < NaiveDate > ,
8893 time : Option < NaiveTime > ,
8994 offset : & Off ,
9095 items : I ,
9196 locale : Locale ,
92- ) -> DelayedFormat < I >
97+ ) -> DelayedFormat < I , Off >
9398 where
9499 Off : Offset + Display ,
95100 {
96- let name_and_diff = ( offset. to_string ( ) , offset. fix ( ) ) ;
97- DelayedFormat { date, time, off : Some ( name_and_diff) , items, locale }
101+ DelayedFormat { date, time, off : Some ( offset. clone ( ) ) , items, locale }
98102 }
99103
100104 fn format ( & self , w : & mut impl Write ) -> fmt:: Result {
@@ -191,7 +195,7 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
191195 write_n ( w, 9 , ( t. nanosecond ( ) % 1_000_000_000 ) as i64 , pad, false )
192196 }
193197 ( Timestamp , Some ( d) , Some ( t) ) => {
194- let offset = self . off . as_ref ( ) . map ( |( _ , o ) | i64:: from ( o. local_minus_utc ( ) ) ) ;
198+ let offset = self . off . as_ref ( ) . map ( |o | i64:: from ( o. fix ( ) . local_minus_utc ( ) ) ) ;
195199 let timestamp = d. and_time ( t) . and_utc ( ) . timestamp ( ) - offset. unwrap_or ( 0 ) ;
196200 write_n ( w, 9 , timestamp, pad, false )
197201 }
@@ -265,50 +269,50 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
265269 ( Internal ( InternalFixed { val : Nanosecond9NoDot } ) , _, Some ( t) , _) => {
266270 write ! ( w, "{:09}" , t. nanosecond( ) % 1_000_000_000 )
267271 }
268- ( TimezoneName , _, _, Some ( ( tz_name , _ ) ) ) => write ! ( w, "{}" , tz_name ) ,
269- ( TimezoneOffset | TimezoneOffsetZ , _, _, Some ( ( _ , off) ) ) => {
272+ ( TimezoneName , _, _, Some ( off ) ) => write ! ( w, "{}" , off ) ,
273+ ( TimezoneOffset | TimezoneOffsetZ , _, _, Some ( off) ) => {
270274 let offset_format = OffsetFormat {
271275 precision : OffsetPrecision :: Minutes ,
272276 colons : Colons :: Maybe ,
273277 allow_zulu : * spec == TimezoneOffsetZ ,
274278 padding : Pad :: Zero ,
275279 } ;
276- offset_format. format ( w, * off)
280+ offset_format. format ( w, off. fix ( ) )
277281 }
278- ( TimezoneOffsetColon | TimezoneOffsetColonZ , _, _, Some ( ( _ , off) ) ) => {
282+ ( TimezoneOffsetColon | TimezoneOffsetColonZ , _, _, Some ( off) ) => {
279283 let offset_format = OffsetFormat {
280284 precision : OffsetPrecision :: Minutes ,
281285 colons : Colons :: Colon ,
282286 allow_zulu : * spec == TimezoneOffsetColonZ ,
283287 padding : Pad :: Zero ,
284288 } ;
285- offset_format. format ( w, * off)
289+ offset_format. format ( w, off. fix ( ) )
286290 }
287- ( TimezoneOffsetDoubleColon , _, _, Some ( ( _ , off) ) ) => {
291+ ( TimezoneOffsetDoubleColon , _, _, Some ( off) ) => {
288292 let offset_format = OffsetFormat {
289293 precision : OffsetPrecision :: Seconds ,
290294 colons : Colons :: Colon ,
291295 allow_zulu : false ,
292296 padding : Pad :: Zero ,
293297 } ;
294- offset_format. format ( w, * off)
298+ offset_format. format ( w, off. fix ( ) )
295299 }
296- ( TimezoneOffsetTripleColon , _, _, Some ( ( _ , off) ) ) => {
300+ ( TimezoneOffsetTripleColon , _, _, Some ( off) ) => {
297301 let offset_format = OffsetFormat {
298302 precision : OffsetPrecision :: Hours ,
299303 colons : Colons :: None ,
300304 allow_zulu : false ,
301305 padding : Pad :: Zero ,
302306 } ;
303- offset_format. format ( w, * off)
307+ offset_format. format ( w, off. fix ( ) )
304308 }
305- ( RFC2822 , Some ( d) , Some ( t) , Some ( ( _ , off) ) ) => {
306- write_rfc2822 ( w, crate :: NaiveDateTime :: new ( d, t) , * off)
309+ ( RFC2822 , Some ( d) , Some ( t) , Some ( off) ) => {
310+ write_rfc2822 ( w, crate :: NaiveDateTime :: new ( d, t) , off. fix ( ) )
307311 }
308- ( RFC3339 , Some ( d) , Some ( t) , Some ( ( _ , off) ) ) => write_rfc3339 (
312+ ( RFC3339 , Some ( d) , Some ( t) , Some ( off) ) => write_rfc3339 (
309313 w,
310314 crate :: NaiveDateTime :: new ( d, t) ,
311- * off,
315+ off. fix ( ) ,
312316 SecondsFormat :: AutoSi ,
313317 false ,
314318 ) ,
@@ -318,7 +322,12 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
318322}
319323
320324#[ cfg( feature = "alloc" ) ]
321- impl < ' a , I : Iterator < Item = B > + Clone , B : Borrow < Item < ' a > > > Display for DelayedFormat < I > {
325+ impl < ' a , I , B , Off > Display for DelayedFormat < I , Off >
326+ where
327+ I : Iterator < Item = B > + Clone ,
328+ B : Borrow < Item < ' a > > ,
329+ Off : Offset + Display ,
330+ {
322331 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
323332 let mut result = String :: new ( ) ;
324333 self . format ( & mut result) ?;
@@ -344,7 +353,7 @@ where
344353 DelayedFormat {
345354 date : date. copied ( ) ,
346355 time : time. copied ( ) ,
347- off : off. cloned ( ) ,
356+ off : off. cloned ( ) . map ( | ( tz_name , offset ) | OffsetWrapper { offset , tz_name } ) ,
348357 items,
349358 locale : default_locale ( ) ,
350359 }
@@ -364,13 +373,35 @@ pub fn format_item(
364373 DelayedFormat {
365374 date : date. copied ( ) ,
366375 time : time. copied ( ) ,
367- off : off. cloned ( ) ,
376+ off : off. cloned ( ) . map ( | ( tz_name , offset ) | OffsetWrapper { offset , tz_name } ) ,
368377 items : [ item] . into_iter ( ) ,
369378 locale : default_locale ( ) ,
370379 }
371380 . fmt ( w)
372381}
373382
383+ /// Only used by the deprecated `format` and `format_item` functions.
384+ #[ cfg( feature = "alloc" ) ]
385+ #[ derive( Clone , Debug ) ]
386+ struct OffsetWrapper {
387+ offset : FixedOffset ,
388+ tz_name : String ,
389+ }
390+
391+ #[ cfg( feature = "alloc" ) ]
392+ impl Offset for OffsetWrapper {
393+ fn fix ( & self ) -> FixedOffset {
394+ self . offset
395+ }
396+ }
397+
398+ #[ cfg( feature = "alloc" ) ]
399+ impl Display for OffsetWrapper {
400+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
401+ f. write_str ( & self . tz_name )
402+ }
403+ }
404+
374405#[ cfg( any( feature = "alloc" , feature = "serde" ) ) ]
375406impl OffsetFormat {
376407 /// Writes an offset from UTC with the format defined by `self`.
0 commit comments