如何将java.util.Date转换为java.sql.Date?


453

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

我很惊讶地发现它不能隐式或显式地进行转换-但我什至不知道该怎么做,因为Java API对我来说还很新。


您可以在此处找到类似的问题 stackoverflow.com/questions/12131068/…–
Lem

对我来说,事实证明我不需要转换。import java.sql.*我的代码中有一个,它覆盖了java.util.date,因此在分配对后者(而不是第一个)合适的日期值时造成麻烦。HTH
HumanInDisguise 2015年

1
@DavidAckerman您了解java.util.Date是日期时间,但是java.sql.Date只是没有时间的日期吗?(实际上有一天的时间,但是会被忽略,这是对类设计的错误处理)。在SQL中,DATE表示仅日期。
罗勒·布尔克

2
我的确没有意识到'09的细微差别,并且由于这个问题如此流行,我将可接受的答案更改为既现代又完整的答案。谢谢各位的意见!
David Ackerman

Answers:


89

tl; dr

如何将java.util.Date转换为java.sql.Date?

别。这两类都过时了。

  • 在JDBC 4.2或更高版本中,请使用java.time类而不是legacy java.util.Datejava.sql.Date
  • 如果与尚未更新为java.time的代码进行互操作,则与java.time进行相互转换。

使用的示例查询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(旧式和现代)和SQL标准中的日期时间类型表。

java.time

在Java 8和更高版本中,新的java.time软件包取代了与Java早期版本捆绑在一起的麻烦的旧日期时间类。请参阅Oracle教程。许多功能已被后移植到Java 6和7在ThreeTen-反向移植和在进一步适于到Android ThreeTenABP

一个SQL数据类型 DATE,就是要日期而已,没有时区没有时间的日和。直到java.time.LocalDateJava 8 为止,Java 才从未有过这样的类† 。让我们通过根据特定时区获取今天的日期来创建这样的值(时区对于确定日期是重要的,因为巴黎要比蒙特利尔早得多,例)。

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规范,你应该能够传递一个LocalDate通过setObject一个PreparedStatement存储到一个SQL日期字段。

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

尽管应避免使用旧的日期时间类,但在使用现有代码时可能会被迫使用。如果是这样,则可以与java.time进行相互转换。

完成该Instant课程,该课程代表UTC时间轴上的时刻。An的Instant概念与相似java.util.Date。但是请注意,Instant它的分辨率最高为纳秒,而分辨率java.util.Date只有毫秒

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

Instant instant = myUtilDate.toInstant();

要确定日期,我们需要时区的上下文。对于任何给定时刻,日期都会随时区在全球范围内变化。申请ZoneId获得ZonedDateTime

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

†java.sql.Date类假装为仅日期,没有一天的时间,但实际上一天的时间,已调整为午夜时间。令人困惑?是的,旧的日期时间类很烂。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

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

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

与哪个版本的Java或Android一起使用的哪个java.time库的表

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多


478

没关系....

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


34
这不是显式转换!在Javadoc中:“如果给定的毫秒值包含时间信息,则驱动程序会将时间分量设置为默认时区(运行应用程序的Java虚拟机的时区)中的时间,该时间对应于格林尼治标准时间零。因此,无论您在java.util.Date上的时间如何,它都将作为00:00:00插入到数据类型设置为DATE的列中。

1
@David Ackerman .....此方法返回的epochseconds毫秒数1,JAN,1970。但是,如果我们要在此日期之前存储某个人的日期,该怎么办?...或类似的东西0000-00-00 as default
Arjun KP 2012年

31
在我的情况下,正确的答案是<code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utilDate.getTime()); </ code>,因为它保留了时间字段。
Alberto de Paola 2012年

2
@ wired00是的,与Java的早期版本捆绑在一起的旧的日期时间类是一团糟,设计不良,包括一些粗暴的hacks。尽可能尝试在Java 8及更高版本中使用新的java.time框架。这些新阶级取代了旧阶级。java.time类和旧类具有一些来回转换的便捷方法-在我们等待JDBC驱动程序更新以直接利用新的java.time类型时非常有用。
罗勒·布尔克

1
@ wired00有关如何使用java.time,请参阅有关此问题的新答案。还要搜索StackOverflow以获取更多示例。
罗勒·布尔克

39

使用其他答案,您可能会在时间信息方面遇到麻烦(将日期与意外结果进行比较!)

我建议:

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);

5
如果他使用java.sql.Date作为数据库中的Date列,则该时间信息将被截断。我认为您对解决方案的设计过高。
darioo 2010年

4
是的,也许我做到了。有时我需要将java.sql.Data与当前日期进行比较,恕我直言,这是最好的方法。希望对您有所帮助。
mauretto 2010年

仅供参考,麻烦的旧日期时间类(如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在已成为旧版)被Java 8及更高版本中内置的java.time类取代。请参见Oracle 教程
罗勒·布尔克

当然,这个话题大约在10年前的Java 8之前
。– mauretto

26

此函数将从java date对象返回转换后的SQL日期。

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}

18

转换java.util.Datajava.sql.Data会松散小时,分钟和秒。因此,如果可能的话,我建议您这样使用java.sql.Timestamp

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

有关更多信息,您可以检查此问题


16

在我从JXDatePicker(Java日历)中选择日期并将其作为SQL Date类型存储在数据库中的情况下,下面的工作很好..

java.sql.Date date = new java.sql.Date(pickedDate.getDate().getTime());

其中pickedDate是JXDatePicker的对象


5

此函数将从java date对象返回转换后的SQL日期。

public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }

3

首先格式化java.util.Date。然后使用格式化的日期获取java.sql.Date中的日期

java.util.Date utilDate = "Your date"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String stringDate= dateFormat.format(utilDate);
final java.sql.Date sqlDate=  java.sql.Date.valueOf(stringDate);

2

在这里,将Util Date转换为Sql date和ya的示例,这是我在项目中使用的一个示例,也可能对您有所帮助。

java.util.Date utilStartDate = table_Login.getDob();(orwhat ever date your give form obj)
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());(converting date)

2

我是新手:经过大量运行后,此方法可行。思想可能有用

     String bufDt =  bDOB.getText();  //data from form
     DateFormat dF = new SimpleDateFormat("dd-MM-yyyy"); //data in form is in this format
     Date bbdt = (Date)dF.parse(bufDt);  // string data is converted into java util date
     DateFormat dsF = new SimpleDateFormat("yyyy-MM-dd"); //converted date is reformatted for conversion to sql.date
     String ndt = dsF.format(bbdt); // java util date is converted to compatible java sql date
     java.sql.Date sqlDate=  java.sql.Date.valueOf(ndt);  // finally data from the form is convered to java sql. date for placing in database

仅供参考,麻烦的旧日期时间类(如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在已成为旧版)被Java 8及更高版本中内置的java.time类取代。请参见Oracle 教程
罗勒·布尔克

2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

这里的javaDate是java.util.Date的实例


1
与David Ackerman,chetan和Tanmay kumar shaw的答案相比,它似乎并没有增加任何新内容,是吗?
Ole VV

1

比较两个日期(util.date或sql.date)的方法

 public static boolean isSameDay(Date a, Date b) {
    Calendar calA = new GregorianCalendar();
    calA.setTime(a);

    Calendar calB = new GregorianCalendar();
    calB.setTime(b);

    final int yearA = calA.get(Calendar.YEAR);
    final int monthA = calA.get(Calendar.MONTH);
    final int dayA = calA.get(Calendar.DAY_OF_YEAR);

    final int yearB = calB.get(Calendar.YEAR);
    final int monthB = calB.get(Calendar.MONTH);
    final int dayB = calB.get(Calendar.DAY_OF_YEAR);

    return yearA == yearB && monthA == monthB && dayA == dayB;
}

0

试试这个

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;
}

-1

我认为最好的转换方法是:

static java.sql.Timestamp SQLDateTime(Long utilDate) {
    return new java.sql.Timestamp(utilDate);
}

Date date = new Date();
java.sql.Timestamp dt = SQLDateTime(date.getTime());

如果要将dt变量插入到SQL表中,可以执行以下操作:

insert into table (expireAt) values ('"+dt+"');

1
这似乎与一年前发布的答案基本相同。
伯恩哈德·巴克

-3

我正在使用以下代码,请尝试一下

DateFormat fm= new SimpleDateFormatter();

指定所需日期的格式,例如,"DD-MM_YYYY"'YYYY-mm-dd' 使用java Date数据类型作为

fm.format("object of java.util.date");

然后它将解析您的日期


-3

您可以使用此方法将util date转换为sql date,

DateUtilities.convertUtilDateToSql(java.util.Date)

标准Java库中没有DateUtilities类(通过快速Google搜索,我什至无法在任何地方找到此方法)。如果这是来自特定库,则可能要多说一些并包括指向文档的链接。
Bernhard Barker,

-4

我正在尝试下面的工作正常的编码。

java.util.Date utilDate =新的java.util.Date();
java.sql.Date sqlDate =新的java.sql.Date(utilDate);


-8

如果您使用的是MySQL,则可以将日期列传递给该日期的字符串表示形式

所以我使用DateFormatter类对其进行格式化,然后在sql语句或prepared语句中将其设置为String

这是代码图:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

字符串日期= converUtilDateToSqlDate(otherTransaction.getTransDate());

//然后在您的sql语句中传递此日期


14
欢迎来到stackoverflow,我对您的回答有一些评论。问题是“如何将java.util.Date转换为java.sql.Date”。您粘贴的代码将java.util.Date格式化为yyyy-MM-dd。在这种情况下,这实际上用途有限,因为您应该将java.sql.Date直接传递给jdbc驱动程序,而不是将其作为字符串来使用。
jontro 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.