我试图使用java.util.Date作为输入,然后用它创建查询-所以我需要一个java.sql.Date。

我惊讶地发现它不能隐式或显式地进行转换——但我甚至不知道如何做到这一点,因为Java API对我来说仍然相当新。


当前回答

博士tl;

如何转换java.util.Date到java.sql.Date?

不喜欢。

这两个Date类都过时了。Sun、Oracle和JCP社区多年前就放弃了那些遗留的日期-时间类,一致采用了定义java的JSR 310。时间类。

使用java。JDBC 4.2或更高版本的java.util.Date & java.sql.Date。 转换为/从java。如果与尚未更新到java.time的代码进行交互操作,则为Time。

Legacy Modern Conversion
java.util.Date java.time.Instant java.util.Date.toInstant()
java.util.Date.from( Instant )
java.sql.Date java.time.LocalDate java.sql.Date.toLocalDate()
java.sql.Date.valueOf( LocalDate )

使用PreparedStatement的示例查询。

myPreparedStatement.setObject( 
    … ,                                         // Specify the ordinal number of which argument in SQL statement.
    myJavaUtilDate.toInstant()                  // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
        .atZone( ZoneId.of( "Africa/Tunis" ) )  // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
        .toLocalDate()                          // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)

更换:

Instant而不是java.util. date两者都表示UTC时间。但是现在用纳秒代替毫秒。 LocalDate而不是java.sql. date两者都表示一个只有日期的值,没有日期和时区。

细节

如果您试图使用只有日期的值(没有日期,没有时区),请使用LocalDate类而不是java.util.Date。

java.time

在Java 8及以后版本中,与早期版本的Java捆绑在一起的麻烦的旧日期-时间类已经被新的Java所取代。包的时间。参见Oracle教程。在ThreeTen-Backport中,许多功能已经被向后移植到Java 6和7,并在ThreeTenABP中进一步适应Android。

SQL数据类型DATE意味着只有日期,没有日期和时区。在Java 8中Java .time. localdate之前,Java从来没有这样的类†。让我们通过根据特定的时区获取今天的日期来创建这样一个值(例如,时区在确定日期时很重要,因为巴黎的新一天比Montréal的黎明早)。

LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );  // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".

在这一点上,我们可能已经完成了。如果您的JDBC驱动程序符合JDBC 4.2规范,您应该能够通过PreparedStatement上的setObject传递一个LocalDate来存储到SQL DATE字段中。

myPreparedStatement.setObject( 1 , localDate );

同样,使用ResultSet::getObject从SQL DATE列获取Java LocalDate对象。在第二个参数中指定类使您的代码是类型安全的。

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

换句话说,整个问题在JDBC 4.2或更高版本下是不相关的。

如果您的JDBC驱动程序没有以这种方式执行,则需要返回到java。sql类型。

转换为java.sql.Date

要进行转换,请使用添加到旧日期-时间类中的新方法。我们可以调用java.sql.Date.valueOf(…)来转换LocalDate。

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

相反的方向。

LocalDate localDate = sqlDate.toLocalDate();

从java.util.Date转换

虽然您应该避免使用旧的date-time类,但在使用现有代码时可能会被迫这样做。如果是,您可以转换为/从java.time。

遍历Instant类,它表示UTC时间轴上的一个时刻。Instant在思想上类似于java.util.Date。但是请注意,Instant的分辨率高达纳秒,而java.util.Date的分辨率只有毫秒。

要进行转换,请使用添加到旧类中的新方法。例如,java.util.Date.from(Instant)和java.util.Date::toInstant。

Instant instant = myUtilDate.toInstant();

为了确定日期,我们需要时区的上下文。对于任何给定的时刻,日期在全球各地因时区而异。应用ZoneId获取zoneeddatetime。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

†java.sql.Date类假装只有日期,没有日期时间,但实际上是一个日期时间,调整为午夜时间。困惑吗?是的,旧的日期时间类是一团糟。


关于java.time

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

Joda-Time项目现在处于维护模式,建议迁移到java。时间类。

你可以交换java。Time对象直接使用数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java。sql。*类。Hibernate 5和JPA 2.2支持java.time。

从哪里获取java。时间类?

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 brought 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 (26+) bundle implementations of the java.time classes. For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android. If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

其他回答

博士tl;

如何转换java.util.Date到java.sql.Date?

不喜欢。

这两个Date类都过时了。Sun、Oracle和JCP社区多年前就放弃了那些遗留的日期-时间类,一致采用了定义java的JSR 310。时间类。

使用java。JDBC 4.2或更高版本的java.util.Date & java.sql.Date。 转换为/从java。如果与尚未更新到java.time的代码进行交互操作,则为Time。

Legacy Modern Conversion
java.util.Date java.time.Instant java.util.Date.toInstant()
java.util.Date.from( Instant )
java.sql.Date java.time.LocalDate java.sql.Date.toLocalDate()
java.sql.Date.valueOf( LocalDate )

使用PreparedStatement的示例查询。

myPreparedStatement.setObject( 
    … ,                                         // Specify the ordinal number of which argument in SQL statement.
    myJavaUtilDate.toInstant()                  // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
        .atZone( ZoneId.of( "Africa/Tunis" ) )  // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
        .toLocalDate()                          // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)

更换:

Instant而不是java.util. date两者都表示UTC时间。但是现在用纳秒代替毫秒。 LocalDate而不是java.sql. date两者都表示一个只有日期的值,没有日期和时区。

细节

如果您试图使用只有日期的值(没有日期,没有时区),请使用LocalDate类而不是java.util.Date。

java.time

在Java 8及以后版本中,与早期版本的Java捆绑在一起的麻烦的旧日期-时间类已经被新的Java所取代。包的时间。参见Oracle教程。在ThreeTen-Backport中,许多功能已经被向后移植到Java 6和7,并在ThreeTenABP中进一步适应Android。

SQL数据类型DATE意味着只有日期,没有日期和时区。在Java 8中Java .time. localdate之前,Java从来没有这样的类†。让我们通过根据特定的时区获取今天的日期来创建这样一个值(例如,时区在确定日期时很重要,因为巴黎的新一天比Montréal的黎明早)。

LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );  // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".

在这一点上,我们可能已经完成了。如果您的JDBC驱动程序符合JDBC 4.2规范,您应该能够通过PreparedStatement上的setObject传递一个LocalDate来存储到SQL DATE字段中。

myPreparedStatement.setObject( 1 , localDate );

同样,使用ResultSet::getObject从SQL DATE列获取Java LocalDate对象。在第二个参数中指定类使您的代码是类型安全的。

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

换句话说,整个问题在JDBC 4.2或更高版本下是不相关的。

如果您的JDBC驱动程序没有以这种方式执行,则需要返回到java。sql类型。

转换为java.sql.Date

要进行转换,请使用添加到旧日期-时间类中的新方法。我们可以调用java.sql.Date.valueOf(…)来转换LocalDate。

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

相反的方向。

LocalDate localDate = sqlDate.toLocalDate();

从java.util.Date转换

虽然您应该避免使用旧的date-time类,但在使用现有代码时可能会被迫这样做。如果是,您可以转换为/从java.time。

遍历Instant类,它表示UTC时间轴上的一个时刻。Instant在思想上类似于java.util.Date。但是请注意,Instant的分辨率高达纳秒,而java.util.Date的分辨率只有毫秒。

要进行转换,请使用添加到旧类中的新方法。例如,java.util.Date.from(Instant)和java.util.Date::toInstant。

Instant instant = myUtilDate.toInstant();

为了确定日期,我们需要时区的上下文。对于任何给定的时刻,日期在全球各地因时区而异。应用ZoneId获取zoneeddatetime。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

†java.sql.Date类假装只有日期,没有日期时间,但实际上是一个日期时间,调整为午夜时间。困惑吗?是的,旧的日期时间类是一团糟。


关于java.time

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

Joda-Time项目现在处于维护模式,建议迁移到java。时间类。

你可以交换java。Time对象直接使用数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java。sql。*类。Hibernate 5和JPA 2.2支持java.time。

从哪里获取java。时间类?

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 brought 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 (26+) bundle implementations of the java.time classes. For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android. If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

将java.util.Date转换为java.sql.Date将丢失小时、分钟和秒。所以如果可能的话,我建议你像这样使用java.sql.Timestamp:

prepareStatement.setTimestamp(1, new Timestamp(utilDate.getTime()));

要了解更多信息,您可以检查这个问题。

试试这个

public static String toMysqlDateStr(Date date) {
    String dateForMySql = "";
    if (date == null) {
        dateForMySql = null;
    } else {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateForMySql = sdf.format(date);
    }

    return dateForMySql;
}

别介意…

public class MainClass {

  public static void main(String[] args) {
    java.util.Date utilDate = new java.util.Date();
    java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    System.out.println("utilDate:" + utilDate);
    System.out.println("sqlDate:" + sqlDate);

  }

}

解释了它。链接是http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm

对于另一个答案,你可能会遇到时间信息的问题(比较日期和意想不到的结果!)

我建议:

java.util.Calendar cal = Calendar.getInstance();
java.util.Date utilDate = new java.util.Date(); // your util date
cal.setTime(utilDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);    
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime()); // your sql date
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);