@@ -202,20 +202,31 @@ void should_recognize_patterns_of_second_precision(final String pattern) {
202202 assertPatternPrecision (pattern , ChronoUnit .SECONDS );
203203 }
204204
205- @ ParameterizedTest
206- @ ValueSource (
207- strings = {
205+ static Stream <String > should_recognize_patterns_of_minute_precision () {
206+ Stream <String > stream = Stream .of (
208207 // Basics
209208 "m" ,
210209 "mm" ,
210+ "Z" ,
211+ "x" ,
212+ "X" ,
213+ "O" ,
214+ "z" ,
215+ "VV" ,
211216 // Mixed with other stuff
212217 "yyyy-MM-dd HH:mm" ,
213218 "yyyy-MM-dd'T'HH:mm" ,
214219 "HH:mm" ,
220+ "yyyy-MM-dd HH x" ,
221+ "yyyy-MM-dd'T'HH XX" ,
215222 // Single-quoted text containing nanosecond and millisecond directives
216223 "yyyy-MM-dd'S'HH:mm" ,
217- "yyyy-MM-dd'n'HH:mm"
218- })
224+ "yyyy-MM-dd'n'HH:mm" );
225+ return Constants .JAVA_MAJOR_VERSION > 8 ? Stream .concat (stream , Stream .of ("v" )) : stream ;
226+ }
227+
228+ @ ParameterizedTest
229+ @ MethodSource
219230 void should_recognize_patterns_of_minute_precision (final String pattern ) {
220231 assertPatternPrecision (pattern , ChronoUnit .MINUTES );
221232 }
@@ -236,28 +247,71 @@ static List<String> hourPrecisionPatterns() {
236247 "K" ,
237248 "k" ,
238249 "H" ,
239- "Z" ,
240- "x" ,
241- "X" ,
242- "O" ,
243- "z" ,
244- "VV" ,
245250 // Mixed with other stuff
246251 "yyyy-MM-dd HH" ,
247252 "yyyy-MM-dd'T'HH" ,
248- "yyyy-MM-dd HH x" ,
249- "yyyy-MM-dd'T'HH XX" ,
250253 "ddHH" ,
251254 // Single-quoted text containing nanosecond and millisecond directives
252255 "yyyy-MM-dd'S'HH" ,
253256 "yyyy-MM-dd'n'HH" ));
254257 if (Constants .JAVA_MAJOR_VERSION > 8 ) {
255258 java8Patterns .add ("B" );
256- java8Patterns .add ("v" );
257259 }
258260 return java8Patterns ;
259261 }
260262
263+ static Stream <Arguments > dynamic_pattern_should_correctly_determine_precision () {
264+ // When no a precise unit is not available, uses the closest smaller unit.
265+ return Stream .of (
266+ Arguments .of ("G" , ChronoUnit .ERAS ),
267+ Arguments .of ("u" , ChronoUnit .YEARS ),
268+ Arguments .of ("D" , ChronoUnit .DAYS ),
269+ Arguments .of ("M" , ChronoUnit .MONTHS ),
270+ Arguments .of ("L" , ChronoUnit .MONTHS ),
271+ Arguments .of ("d" , ChronoUnit .DAYS ),
272+ Arguments .of ("Q" , ChronoUnit .MONTHS ),
273+ Arguments .of ("q" , ChronoUnit .MONTHS ),
274+ Arguments .of ("Y" , ChronoUnit .YEARS ),
275+ Arguments .of ("w" , ChronoUnit .WEEKS ),
276+ Arguments .of ("W" , ChronoUnit .DAYS ), // The month can change in the middle of the week
277+ Arguments .of ("F" , ChronoUnit .DAYS ), // The month can change in the middle of the week
278+ Arguments .of ("E" , ChronoUnit .DAYS ),
279+ Arguments .of ("e" , ChronoUnit .DAYS ),
280+ Arguments .of ("c" , ChronoUnit .DAYS ),
281+ Arguments .of ("a" , ChronoUnit .HOURS ), // Let us round it down
282+ Arguments .of ("h" , ChronoUnit .HOURS ),
283+ Arguments .of ("K" , ChronoUnit .HOURS ),
284+ Arguments .of ("k" , ChronoUnit .HOURS ),
285+ Arguments .of ("H" , ChronoUnit .HOURS ),
286+ Arguments .of ("m" , ChronoUnit .MINUTES ),
287+ Arguments .of ("s" , ChronoUnit .SECONDS ),
288+ Arguments .of ("S" , ChronoUnit .MILLIS ),
289+ Arguments .of ("SS" , ChronoUnit .MILLIS ),
290+ Arguments .of ("SSS" , ChronoUnit .MILLIS ),
291+ Arguments .of ("SSSS" , ChronoUnit .MICROS ),
292+ Arguments .of ("SSSSS" , ChronoUnit .MICROS ),
293+ Arguments .of ("SSSSSS" , ChronoUnit .MICROS ),
294+ Arguments .of ("SSSSSSS" , ChronoUnit .NANOS ),
295+ Arguments .of ("SSSSSSSS" , ChronoUnit .NANOS ),
296+ Arguments .of ("SSSSSSSSS" , ChronoUnit .NANOS ),
297+ Arguments .of ("A" , ChronoUnit .MILLIS ),
298+ Arguments .of ("n" , ChronoUnit .NANOS ),
299+ Arguments .of ("N" , ChronoUnit .NANOS ),
300+ // Time zones can change in the middle of a UTC hour (e.g. India)
301+ Arguments .of ("VV" , ChronoUnit .MINUTES ),
302+ Arguments .of ("z" , ChronoUnit .MINUTES ),
303+ Arguments .of ("O" , ChronoUnit .MINUTES ),
304+ Arguments .of ("X" , ChronoUnit .MINUTES ),
305+ Arguments .of ("x" , ChronoUnit .MINUTES ),
306+ Arguments .of ("Z" , ChronoUnit .MINUTES ));
307+ }
308+
309+ @ ParameterizedTest
310+ @ MethodSource
311+ void dynamic_pattern_should_correctly_determine_precision (String singlePattern , ChronoUnit expectedPrecision ) {
312+ assertThat (pDyn (singlePattern ).precision ).isEqualTo (expectedPrecision );
313+ }
314+
261315 private static void assertPatternPrecision (final String pattern , final ChronoUnit expectedPrecision ) {
262316 final InstantPatternFormatter formatter =
263317 new InstantPatternDynamicFormatter (pattern , Locale .getDefault (), TimeZone .getDefault ());
0 commit comments