16
16
*/
17
17
package org .apache .commons .beanutils2 .converters ;
18
18
19
+ import org .apache .commons .beanutils2 .ConversionException ;
20
+
19
21
import java .text .DateFormat ;
20
22
import java .text .ParsePosition ;
21
23
import java .text .SimpleDateFormat ;
25
27
import java .time .OffsetDateTime ;
26
28
import java .time .ZoneId ;
27
29
import java .time .ZonedDateTime ;
30
+ import java .time .format .DateTimeParseException ;
28
31
import java .util .Calendar ;
29
32
import java .util .Date ;
30
33
import java .util .Locale ;
31
34
import java .util .TimeZone ;
32
35
33
- import org .apache .commons .beanutils2 .ConversionException ;
34
-
35
36
/**
36
37
* {@link org.apache.commons.beanutils2.Converter} implementation
37
38
* that handles conversion to and from <b>date/time</b> objects.
44
45
* <li>{@code java.time.LocalDate}</li>
45
46
* <li>{@code java.time.LocalDateTime}</li>
46
47
* <li>{@code java.time.OffsetDateTime}</li>
48
+ * <li>{@code java.time.Instant}</li>
47
49
* <li>{@code java.time.ZonedDateTime}</li>
48
50
* <li>{@code java.sql.Date}</li>
49
51
* <li>{@code java.sql.Time}</li>
@@ -228,19 +230,21 @@ protected String convertToString(final Object value) throws Throwable {
228
230
229
231
Date date = null ;
230
232
if (value instanceof Date ) {
231
- date = (Date )value ;
233
+ date = (Date ) value ;
232
234
} else if (value instanceof Calendar ) {
233
- date = ((Calendar )value ).getTime ();
235
+ date = ((Calendar ) value ).getTime ();
234
236
} else if (value instanceof Long ) {
235
- date = new Date (((Long )value ).longValue ());
237
+ date = new Date (((Long ) value ).longValue ());
236
238
} else if (value instanceof LocalDateTime ) {
237
- date = java .sql .Timestamp .valueOf (((LocalDateTime )value ));
239
+ date = java .sql .Timestamp .valueOf (((LocalDateTime ) value ));
238
240
} else if (value instanceof LocalDate ) {
239
- date = java .sql .Date .valueOf (((LocalDate )value ));
241
+ date = java .sql .Date .valueOf (((LocalDate ) value ));
240
242
} else if (value instanceof ZonedDateTime ) {
241
- date = Date .from (((ZonedDateTime )value ).toInstant ());
243
+ date = Date .from (((ZonedDateTime ) value ).toInstant ());
242
244
} else if (value instanceof OffsetDateTime ) {
243
- date = Date .from (((OffsetDateTime )value ).toInstant ());
245
+ date = Date .from (((OffsetDateTime ) value ).toInstant ());
246
+ } else if (value instanceof Instant ) {
247
+ date = Date .from (((Instant ) value ));
244
248
}
245
249
246
250
String result = null ;
@@ -260,7 +264,7 @@ protected String convertToString(final Object value) throws Throwable {
260
264
result = value .toString ();
261
265
if (log ().isDebugEnabled ()) {
262
266
log ().debug (" Converted to String using toString() '" + result + "'" );
263
- }
267
+ }
264
268
}
265
269
return result ;
266
270
}
@@ -277,6 +281,7 @@ protected String convertToString(final Object value) throws Throwable {
277
281
* <li>{@code java.time.LocalDate}</li>
278
282
* <li>{@code java.time.LocalDateTime}</li>
279
283
* <li>{@code java.time.OffsetDateTime}</li>
284
+ * <li>{@code java.time.Instant}</li>
280
285
* <li>{@code java.time.ZonedDateTime}</li>
281
286
* <li>{@code java.sql.Date}</li>
282
287
* <li>{@code java.sql.Time}</li>
@@ -320,46 +325,51 @@ protected <T> T convertToType(final Class<T> targetType, final Object value) thr
320
325
321
326
// Handle Date (includes java.sql.Date & java.sql.Time)
322
327
if (value instanceof Date ) {
323
- final Date date = (Date )value ;
328
+ final Date date = (Date ) value ;
324
329
return toDate (targetType , date .getTime ());
325
330
}
326
331
327
332
// Handle Calendar
328
333
if (value instanceof Calendar ) {
329
- final Calendar calendar = (Calendar )value ;
334
+ final Calendar calendar = (Calendar ) value ;
330
335
return toDate (targetType , calendar .getTime ().getTime ());
331
336
}
332
337
333
338
// Handle Long
334
339
if (value instanceof Long ) {
335
- final Long longObj = (Long )value ;
340
+ final Long longObj = (Long ) value ;
336
341
return toDate (targetType , longObj .longValue ());
337
342
}
338
343
339
344
// Handle LocalDate
340
345
if (value instanceof LocalDate ) {
341
- final LocalDate date = (LocalDate )value ;
346
+ final LocalDate date = (LocalDate ) value ;
342
347
return toDate (targetType , date .atStartOfDay (getZoneId ()).toInstant ().toEpochMilli ());
343
348
}
344
349
345
350
// Handle LocalDateTime
346
351
if (value instanceof LocalDateTime ) {
347
- final LocalDateTime date = (LocalDateTime )value ;
352
+ final LocalDateTime date = (LocalDateTime ) value ;
348
353
return toDate (targetType , date .atZone (getZoneId ()).toInstant ().toEpochMilli ());
349
354
}
350
355
351
356
// Handle ZonedDateTime
352
357
if (value instanceof ZonedDateTime ) {
353
- final ZonedDateTime date = (ZonedDateTime )value ;
358
+ final ZonedDateTime date = (ZonedDateTime ) value ;
354
359
return toDate (targetType , date .toInstant ().toEpochMilli ());
355
360
}
356
361
357
362
// Handle OffsetDateTime
358
363
if (value instanceof OffsetDateTime ) {
359
- final OffsetDateTime date = (OffsetDateTime )value ;
364
+ final OffsetDateTime date = (OffsetDateTime ) value ;
360
365
return toDate (targetType , date .toInstant ().toEpochMilli ());
361
366
}
362
367
368
+ if (value instanceof Instant ) {
369
+ final Instant date = (Instant ) value ;
370
+ return toDate (targetType , date .toEpochMilli ());
371
+ }
372
+
363
373
// Convert all other types to String & handle
364
374
final String stringValue = toTrim (value );
365
375
if (stringValue .isEmpty ()) {
@@ -454,6 +464,10 @@ private <T> T toDate(final Class<T> type, final long value) {
454
464
return type .cast (offsetDateTime );
455
465
}
456
466
467
+ if (type .equals (Instant .class )) {
468
+ return type .cast (Instant .ofEpochMilli (value ));
469
+ }
470
+
457
471
// java.util.Calendar
458
472
if (type .equals (Calendar .class )) {
459
473
Calendar calendar = null ;
@@ -487,6 +501,7 @@ private <T> T toDate(final Class<T> type, final long value) {
487
501
* <li>{@code java.sql.Date}</li>
488
502
* <li>{@code java.sql.Time}</li>
489
503
* <li>{@code java.sql.Timestamp}</li>
504
+ * <li>{@code java.time.Instant}</li>
490
505
* </ul>
491
506
* <p>
492
507
* <strong>N.B.</strong> No default String conversion
@@ -530,6 +545,14 @@ private <T> T toDate(final Class<T> type, final String value) {
530
545
}
531
546
}
532
547
548
+ if (type .equals (Instant .class )) {
549
+ try {
550
+ return type .cast (Instant .parse (value ));
551
+ } catch (final DateTimeParseException ex ) {
552
+ throw new ConversionException ("String must be in ISO-8601 format to create a java.time.Instant" );
553
+ }
554
+ }
555
+
533
556
final String msg = toString (getClass ()) + " does not support default String to '"
534
557
+ toString (type ) + "' conversion." ;
535
558
if (log ().isWarnEnabled ()) {
0 commit comments