java.util.Date vs java.sql.Date

前端 未结 7 2089
青春惊慌失措
青春惊慌失措 2020-11-22 05:13

java.util.Date vs java.sql.Date: when to use which and why?

7条回答
  •  故里飘歌
    2020-11-22 05:40

    tl;dr

    Use neither.

    • java.time.Instant replaces java.util.Date
    • java.time.LocalDate replaces java.sql.Date

    Neither

    java.util.Date vs java.sql.Date: when to use which and why?

    Both of these classes are terrible, flawed in design and in implementation. Avoid like the Plague Coronavirus.

    Instead use java.time classes, defined in in JSR 310. These classes are an industry-leading framework for working with date-time handling. These supplant entirely the bloody awful legacy classes such as Date, Calendar, SimpleDateFormat, and such.

    java.util.Date

    The first, java.util.Date is meant to represent a moment in UTC, meaning an offset from UTC of zero hours-minutes-seconds.

    java.time.Instant

    Now replaced by java.time.Instant.

    Instant instant = Instant.now() ;  // Capture the current moment as seen in UTC.
    

    java.time.OffsetDateTime

    Instant is the basic building-block class of java.time. For more flexibility, use OffsetDateTime set to ZoneOffset.UTC for the same purpose: representing a moment in UTC.

    OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
    

    You can send this object to a database by using PreparedStatement::setObject with JDBC 4.2 or later.

    myPreparedStatement.setObject( … , odt ) ;
    

    Retrieve.

    OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
    

    java.sql.Date

    The java.sql.Date class is also terrible and obsolete.

    This class is meant to represent a date only, without a time-of-day and without a time zone. Unfortunately, in a terrible hack of a design, this class inherits from java.util.Date which represents a moment (a date with time-of-day in UTC). So this class is merely pretending to be date-only, while actually carrying a time-of-day and implicit offset of UTC. This causes so much confusion. Never use this class.

    java.time.LocalDate

    Instead, use java.time.LocalDate to track just a date (year, month, day-of-month) without any time-of-day nor any time zone or offset.

    ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
    LocalDate ld = LocalDate.now( z ) ;    // Capture the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
    

    Send to the database.

    myPreparedStatement.setObject( … , ld ) ;
    

    Retrieve.

    LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
    


    About java.time

    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

    Where to obtain the java.time classes?

    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.
    • Java SE 6 and Java SE 7
      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • Android
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

提交回复
热议问题