@@ -115,48 +115,88 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
115
115
fn format_numeric ( & self , w : & mut impl Write , spec : & Numeric , pad : Pad ) -> fmt:: Result {
116
116
use self :: Numeric :: * ;
117
117
118
- let ( width, v) = match ( spec, self . date , self . time ) {
119
- ( Year , Some ( d) , _) => ( 4 , i64:: from ( d. year ( ) ) ) ,
120
- ( YearDiv100 , Some ( d) , _) => ( 2 , i64:: from ( d. year ( ) ) . div_euclid ( 100 ) ) ,
121
- ( YearMod100 , Some ( d) , _) => ( 2 , i64:: from ( d. year ( ) ) . rem_euclid ( 100 ) ) ,
122
- ( IsoYear , Some ( d) , _) => ( 4 , i64:: from ( d. iso_week ( ) . year ( ) ) ) ,
123
- ( IsoYearDiv100 , Some ( d) , _) => ( 2 , i64:: from ( d. iso_week ( ) . year ( ) ) . div_euclid ( 100 ) ) ,
124
- ( IsoYearMod100 , Some ( d) , _) => ( 2 , i64:: from ( d. iso_week ( ) . year ( ) ) . rem_euclid ( 100 ) ) ,
125
- ( Month , Some ( d) , _) => ( 2 , i64:: from ( d. month ( ) ) ) ,
126
- ( Day , Some ( d) , _) => ( 2 , i64:: from ( d. day ( ) ) ) ,
127
- ( WeekFromSun , Some ( d) , _) => ( 2 , i64:: from ( d. weeks_from ( Weekday :: Sun ) ) ) ,
128
- ( WeekFromMon , Some ( d) , _) => ( 2 , i64:: from ( d. weeks_from ( Weekday :: Mon ) ) ) ,
129
- ( IsoWeek , Some ( d) , _) => ( 2 , i64:: from ( d. iso_week ( ) . week ( ) ) ) ,
130
- ( NumDaysFromSun , Some ( d) , _) => ( 1 , i64:: from ( d. weekday ( ) . num_days_from_sunday ( ) ) ) ,
131
- ( WeekdayFromMon , Some ( d) , _) => ( 1 , i64:: from ( d. weekday ( ) . number_from_monday ( ) ) ) ,
132
- ( Ordinal , Some ( d) , _) => ( 3 , i64:: from ( d. ordinal ( ) ) ) ,
133
- ( Hour , _, Some ( t) ) => ( 2 , i64:: from ( t. hour ( ) ) ) ,
134
- ( Hour12 , _, Some ( t) ) => ( 2 , i64:: from ( t. hour12 ( ) . 1 ) ) ,
135
- ( Minute , _, Some ( t) ) => ( 2 , i64:: from ( t. minute ( ) ) ) ,
136
- ( Second , _, Some ( t) ) => ( 2 , i64:: from ( t. second ( ) + t. nanosecond ( ) / 1_000_000_000 ) ) ,
137
- ( Nanosecond , _, Some ( t) ) => ( 9 , i64:: from ( t. nanosecond ( ) % 1_000_000_000 ) ) ,
138
- ( Timestamp , Some ( d) , Some ( t) ) => {
139
- let offset = self . off . as_ref ( ) . map ( |( _, o) | i64:: from ( o. local_minus_utc ( ) ) ) ;
140
- let timestamp = d. and_time ( t) . and_utc ( ) . timestamp ( ) - offset. unwrap_or ( 0 ) ;
141
- ( 1 , timestamp)
118
+ fn write_one ( w : & mut impl Write , v : u8 ) -> fmt:: Result {
119
+ w. write_char ( ( b'0' + v) as char )
120
+ }
121
+
122
+ fn write_two ( w : & mut impl Write , v : u8 , pad : Pad ) -> fmt:: Result {
123
+ let ones = b'0' + v % 10 ;
124
+ match ( v / 10 , pad) {
125
+ ( 0 , Pad :: None ) => { }
126
+ ( 0 , Pad :: Space ) => w. write_char ( ' ' ) ?,
127
+ ( tens, _) => w. write_char ( ( b'0' + tens) as char ) ?,
142
128
}
143
- ( Internal ( _) , _, _) => return Ok ( ( ) ) , // for future expansion
144
- _ => return Err ( fmt:: Error ) , // insufficient arguments for given format
145
- } ;
129
+ w. write_char ( ones as char )
130
+ }
146
131
147
- if ( spec == & Year || spec == & IsoYear ) && !( 0 ..10_000 ) . contains ( & v) {
148
- // non-four-digit years require an explicit sign as per ISO 8601
149
- match pad {
150
- Pad :: None => write ! ( w, "{:+}" , v) ,
151
- Pad :: Zero => write ! ( w, "{:+01$}" , v, width + 1 ) ,
152
- Pad :: Space => write ! ( w, "{:+1$}" , v, width + 1 ) ,
132
+ #[ inline]
133
+ fn write_year ( w : & mut impl Write , year : i32 , pad : Pad ) -> fmt:: Result {
134
+ if ( 1000 ..=9999 ) . contains ( & year) {
135
+ // fast path
136
+ write_hundreds ( w, ( year / 100 ) as u8 ) ?;
137
+ write_hundreds ( w, ( year % 100 ) as u8 )
138
+ } else {
139
+ write_n ( w, 4 , year as i64 , pad, !( 0 ..10_000 ) . contains ( & year) )
153
140
}
154
- } else {
155
- match pad {
156
- Pad :: None => write ! ( w, "{}" , v) ,
157
- Pad :: Zero => write ! ( w, "{:01$}" , v, width) ,
158
- Pad :: Space => write ! ( w, "{:1$}" , v, width) ,
141
+ }
142
+
143
+ fn write_n (
144
+ w : & mut impl Write ,
145
+ n : usize ,
146
+ v : i64 ,
147
+ pad : Pad ,
148
+ always_sign : bool ,
149
+ ) -> fmt:: Result {
150
+ if always_sign {
151
+ match pad {
152
+ Pad :: None => write ! ( w, "{:+}" , v) ,
153
+ Pad :: Zero => write ! ( w, "{:+01$}" , v, n + 1 ) ,
154
+ Pad :: Space => write ! ( w, "{:+1$}" , v, n + 1 ) ,
155
+ }
156
+ } else {
157
+ match pad {
158
+ Pad :: None => write ! ( w, "{}" , v) ,
159
+ Pad :: Zero => write ! ( w, "{:01$}" , v, n) ,
160
+ Pad :: Space => write ! ( w, "{:1$}" , v, n) ,
161
+ }
162
+ }
163
+ }
164
+
165
+ match ( spec, self . date , self . time ) {
166
+ ( Year , Some ( d) , _) => write_year ( w, d. year ( ) , pad) ,
167
+ ( YearDiv100 , Some ( d) , _) => write_two ( w, d. year ( ) . div_euclid ( 100 ) as u8 , pad) ,
168
+ ( YearMod100 , Some ( d) , _) => write_two ( w, d. year ( ) . rem_euclid ( 100 ) as u8 , pad) ,
169
+ ( IsoYear , Some ( d) , _) => write_year ( w, d. iso_week ( ) . year ( ) , pad) ,
170
+ ( IsoYearDiv100 , Some ( d) , _) => {
171
+ write_two ( w, d. iso_week ( ) . year ( ) . div_euclid ( 100 ) as u8 , pad)
172
+ }
173
+ ( IsoYearMod100 , Some ( d) , _) => {
174
+ write_two ( w, d. iso_week ( ) . year ( ) . rem_euclid ( 100 ) as u8 , pad)
175
+ }
176
+ ( Month , Some ( d) , _) => write_two ( w, d. month ( ) as u8 , pad) ,
177
+ ( Day , Some ( d) , _) => write_two ( w, d. day ( ) as u8 , pad) ,
178
+ ( WeekFromSun , Some ( d) , _) => write_two ( w, d. weeks_from ( Weekday :: Sun ) as u8 , pad) ,
179
+ ( WeekFromMon , Some ( d) , _) => write_two ( w, d. weeks_from ( Weekday :: Mon ) as u8 , pad) ,
180
+ ( IsoWeek , Some ( d) , _) => write_two ( w, d. iso_week ( ) . week ( ) as u8 , pad) ,
181
+ ( NumDaysFromSun , Some ( d) , _) => write_one ( w, d. weekday ( ) . num_days_from_sunday ( ) as u8 ) ,
182
+ ( WeekdayFromMon , Some ( d) , _) => write_one ( w, d. weekday ( ) . number_from_monday ( ) as u8 ) ,
183
+ ( Ordinal , Some ( d) , _) => write_n ( w, 3 , d. ordinal ( ) as i64 , pad, false ) ,
184
+ ( Hour , _, Some ( t) ) => write_two ( w, t. hour ( ) as u8 , pad) ,
185
+ ( Hour12 , _, Some ( t) ) => write_two ( w, t. hour12 ( ) . 1 as u8 , pad) ,
186
+ ( Minute , _, Some ( t) ) => write_two ( w, t. minute ( ) as u8 , pad) ,
187
+ ( Second , _, Some ( t) ) => {
188
+ write_two ( w, ( t. second ( ) + t. nanosecond ( ) / 1_000_000_000 ) as u8 , pad)
189
+ }
190
+ ( Nanosecond , _, Some ( t) ) => {
191
+ write_n ( w, 9 , ( t. nanosecond ( ) % 1_000_000_000 ) as i64 , pad, false )
192
+ }
193
+ ( Timestamp , Some ( d) , Some ( t) ) => {
194
+ let offset = self . off . as_ref ( ) . map ( |( _, o) | i64:: from ( o. local_minus_utc ( ) ) ) ;
195
+ let timestamp = d. and_time ( t) . and_utc ( ) . timestamp ( ) - offset. unwrap_or ( 0 ) ;
196
+ write_n ( w, 9 , timestamp, pad, false )
159
197
}
198
+ ( Internal ( _) , _, _) => Ok ( ( ) ) , // for future expansion
199
+ _ => Err ( fmt:: Error ) , // insufficient arguments for given format
160
200
}
161
201
}
162
202
@@ -206,21 +246,21 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
206
246
}
207
247
( Nanosecond3 , _, Some ( t) , _) => {
208
248
w. write_str ( decimal_point ( self . locale ) ) ?;
209
- write ! ( w, "{:03}" , t. nanosecond( ) % 1_000_000_000 / 1_000_000 )
249
+ write ! ( w, "{:03}" , t. nanosecond( ) / 1_000_000 % 1000 )
210
250
}
211
251
( Nanosecond6 , _, Some ( t) , _) => {
212
252
w. write_str ( decimal_point ( self . locale ) ) ?;
213
- write ! ( w, "{:06}" , t. nanosecond( ) % 1_000_000_000 / 1_000 )
253
+ write ! ( w, "{:06}" , t. nanosecond( ) / 1_000 % 1_000_000 )
214
254
}
215
255
( Nanosecond9 , _, Some ( t) , _) => {
216
256
w. write_str ( decimal_point ( self . locale ) ) ?;
217
257
write ! ( w, "{:09}" , t. nanosecond( ) % 1_000_000_000 )
218
258
}
219
259
( Internal ( InternalFixed { val : Nanosecond3NoDot } ) , _, Some ( t) , _) => {
220
- write ! ( w, "{:03}" , t. nanosecond( ) % 1_000_000_000 / 1_000_000 )
260
+ write ! ( w, "{:03}" , t. nanosecond( ) / 1_000_000 % 1_000 )
221
261
}
222
262
( Internal ( InternalFixed { val : Nanosecond6NoDot } ) , _, Some ( t) , _) => {
223
- write ! ( w, "{:06}" , t. nanosecond( ) % 1_000_000_000 / 1_000 )
263
+ write ! ( w, "{:06}" , t. nanosecond( ) / 1_000 % 1_000_000 )
224
264
}
225
265
( Internal ( InternalFixed { val : Nanosecond9NoDot } ) , _, Some ( t) , _) => {
226
266
write ! ( w, "{:09}" , t. nanosecond( ) % 1_000_000_000 )
0 commit comments