Convert java.util.Date to java.time.LocalDate

前端 未结 13 2439
温柔的废话
温柔的废话 2020-11-22 08:45

What is the best way to convert a java.util.Date object to the new JDK 8/JSR-310 java.time.LocalDate?

Date input = new Date();
Loca         


        
13条回答
  •  醉酒成梦
    2020-11-22 09:50

    Better way is:

    Date date = ...;
    Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()
    

    Advantages of this version:

    • works regardless the input is an instance of java.util.Date or it's a subclass of java.sql.Date (unlike @JodaStephen's way). This is common with JDBC-originated data. java.sql.Date.toInstant() always throws an exception.

    • it's the same for JDK8 and JDK7 with JSR-310 backport

    I personally use an utility class (but it is not backport-compatible):

    /**
     * Utilities for conversion between the old and new JDK date types 
     * (between {@code java.util.Date} and {@code java.time.*}).
     * 
     * 

    * All methods are null-safe. */ public class DateConvertUtils { /** * Calls {@link #asLocalDate(Date, ZoneId)} with the system default time zone. */ public static LocalDate asLocalDate(java.util.Date date) { return asLocalDate(date, ZoneId.systemDefault()); } /** * Creates {@link LocalDate} from {@code java.util.Date} or it's subclasses. Null-safe. */ public static LocalDate asLocalDate(java.util.Date date, ZoneId zone) { if (date == null) return null; if (date instanceof java.sql.Date) return ((java.sql.Date) date).toLocalDate(); else return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDate(); } /** * Calls {@link #asLocalDateTime(Date, ZoneId)} with the system default time zone. */ public static LocalDateTime asLocalDateTime(java.util.Date date) { return asLocalDateTime(date, ZoneId.systemDefault()); } /** * Creates {@link LocalDateTime} from {@code java.util.Date} or it's subclasses. Null-safe. */ public static LocalDateTime asLocalDateTime(java.util.Date date, ZoneId zone) { if (date == null) return null; if (date instanceof java.sql.Timestamp) return ((java.sql.Timestamp) date).toLocalDateTime(); else return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDateTime(); } /** * Calls {@link #asUtilDate(Object, ZoneId)} with the system default time zone. */ public static java.util.Date asUtilDate(Object date) { return asUtilDate(date, ZoneId.systemDefault()); } /** * Creates a {@link java.util.Date} from various date objects. Is null-safe. Currently supports:

      *
    • {@link java.util.Date} *
    • {@link java.sql.Date} *
    • {@link java.sql.Timestamp} *
    • {@link java.time.LocalDate} *
    • {@link java.time.LocalDateTime} *
    • {@link java.time.ZonedDateTime} *
    • {@link java.time.Instant} *
    * * @param zone Time zone, used only if the input object is LocalDate or LocalDateTime. * * @return {@link java.util.Date} (exactly this class, not a subclass, such as java.sql.Date) */ public static java.util.Date asUtilDate(Object date, ZoneId zone) { if (date == null) return null; if (date instanceof java.sql.Date || date instanceof java.sql.Timestamp) return new java.util.Date(((java.util.Date) date).getTime()); if (date instanceof java.util.Date) return (java.util.Date) date; if (date instanceof LocalDate) return java.util.Date.from(((LocalDate) date).atStartOfDay(zone).toInstant()); if (date instanceof LocalDateTime) return java.util.Date.from(((LocalDateTime) date).atZone(zone).toInstant()); if (date instanceof ZonedDateTime) return java.util.Date.from(((ZonedDateTime) date).toInstant()); if (date instanceof Instant) return java.util.Date.from((Instant) date); throw new UnsupportedOperationException("Don't know hot to convert " + date.getClass().getName() + " to java.util.Date"); } /** * Creates an {@link Instant} from {@code java.util.Date} or it's subclasses. Null-safe. */ public static Instant asInstant(Date date) { if (date == null) return null; else return Instant.ofEpochMilli(date.getTime()); } /** * Calls {@link #asZonedDateTime(Date, ZoneId)} with the system default time zone. */ public static ZonedDateTime asZonedDateTime(Date date) { return asZonedDateTime(date, ZoneId.systemDefault()); } /** * Creates {@link ZonedDateTime} from {@code java.util.Date} or it's subclasses. Null-safe. */ public static ZonedDateTime asZonedDateTime(Date date, ZoneId zone) { if (date == null) return null; else return asInstant(date).atZone(zone); } }

    The asLocalDate() method here is null-safe, uses toLocalDate(), if input is java.sql.Date (it may be overriden by the JDBC driver to avoid timezone problems or unnecessary calculations), otherwise uses the abovementioned method.

提交回复
热议问题