ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

您可以在此处找到类似的问题stackoverflow.com/questions/12131068/…
对我来说,事实证明我不需要转换。我的代码中有一个 import java.sql.* ,它覆盖了 java.util.date ,因此在分配适用于后者但不是第一个的日期值时会造成麻烦。高温高压
@DavidAckerman您是否了解 java.util.Date 是日期 时间,但 java.sql.Date 只是日期 没有 a一天中的时间? (实际上有一个时间,但它被忽略了,这是对类设计的一个糟糕的修改)在 SQL 中,DATE 表示仅日期。
我确实不知道 09 年的细微差别,而且由于这个问题如此受欢迎,我已将接受的答案更改为更现代和更完整的答案。谢谢各位的意见!

D
David Ackerman

没关系....

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


这不是显式转换!来自 Javadoc:“如果给定的毫秒值包含时间信息,驱动程序会将时间组件设置为默认时区(运行应用程序的 Java 虚拟机的时区)中对应于零 GMT 的时间。”因此,无论您在 java.util.Date 上的时间是多少,它都将作为 00:00:00 插入数据类型设置为 DATE 的列中。
@David Ackerman .....此方法返回 epochseconds,即 1,JAN,1970 之后的毫秒数。但是如果我们想在这个日期之前存储一个人的日期……或者像 0000-00-00 as default 这样的东西怎么办?
在我的情况下,正确的答案是 java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utilDate.getTime());,因为它保留了时间字段。
@wired00 是的,与早期 Java 版本捆绑的旧日期时间类一团糟,设计糟糕,包括一些粗略的黑客攻击。尽可能尝试在 Java 8 及更高版本中使用新的 java.time framework。这些新阶级取代了旧阶级。 java.time 类和旧类有一些方便的来回转换方法——在我们等待更新 JDBC 驱动程序以直接利用新的 java.time 类型时很有用。
@wired00 有关如何使用 java.time,请参阅此问题的 my new Answer。还可以搜索 StackOverflow 以获取更多示例。
B
Basil Bourque

tl;博士

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

不。

Date 两个类都已过时。 SunOracleJCP 社区几年前就放弃了这些旧的日期时间类,一致采用 JSR 310 定义 java.time 类。

在 JDBC 4.2 或更高版本中使用 java.time 类而不是旧的 java.util.Date 和 java.sql.Date。

如果与尚未更新为 java.time 的代码进行互操作,则转换为 java.time 或从 java.time 转换。

传统现代转换 java.util.Date java.time.Instant java.util.Date.toInstant() java.util.Date.from( Instant ) java.sql.Date java.time.Date 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

https://i.stack.imgur.com/bXtIS.png

java.time

在 Java 8 及更高版本中,与早期版本的 Java 捆绑在一起的麻烦的旧日期时间类已被新的 java.time package 取代。见Oracle Tutorial。大部分功能已向后移植到 Java 6 & ThreeTen-Backport 中的 7 并在 ThreeTenABP 中进一步适应 Android。

SQL data type DATE 仅表示日期,没有时间和时区。在 Java 8 中的 java.time.LocalDate 之前,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 driver 符合 JDBC 4.2 spec,您应该能够通过 PreparedStatement 上的 setObject 传递 LocalDate 以存储到 SQL DATE 字段中。

myPreparedStatement.setObject( 1 , localDate );

同样,使用 ResultSet::getObject 从 SQL DATE 列获取 Java LocalDate 对象。在第二个参数中指定类会使您的代码变为 type-safe

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 时间线上的一个时刻。 Instant 在概念上类似于 java.util.Date。但请注意,Instant 的分辨率高达 nanoseconds,而 java.util.Date 的分辨率只有 milliseconds

要进行转换,请使用添加到旧类的新方法。例如,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 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendar 和 & SimpleDateFormat

要了解更多信息,请参阅 Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

Joda-Time 项目现在位于 maintenance mode 中,建议迁移到 java.time 类。

您可以直接与您的数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC driver。不需要字符串,不需要 java.sql.* 类。休眠 5 和JPA 2.2 支持 java.time

从哪里获得 java.time 类?

Java SE 8、Java SE 9、Java SE 10、Java SE 11 及更高版本 - 标准 Java API 的一部分,具有捆绑的实现。 Java 9 带来了一些小功能和修复。

Java 9 带来了一些小功能和修复。

Java SE 6 和 Java SE 7 大多数 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。

大多数 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。

Android 更高版本的 Android (26+) 捆绑了 java.time 类的实现。对于早期的 Android (<26),称为 API 脱糖的过程带来了最初未内置于 Android 中的 java.time 功能的子集。如果脱糖不能提供您所需要的,ThreeTenABP 项目会将 ThreeTen-Backport(上面提到的)适配到 Android。请参阅如何使用 ThreeTenABP……。

更高版本的 Android (26+) 捆绑了 java.time 类的实现。

对于早期的 Android (<26),称为 API 脱糖的过程带来了最初未内置于 Android 中的 java.time 功能的子集。如果脱糖不能提供您所需要的,ThreeTenABP 项目会将 ThreeTen-Backport(上面提到的)适配到 Android。请参阅如何使用 ThreeTenABP……。

如果脱糖不能提供您所需要的,ThreeTenABP 项目会将 ThreeTen-Backport(上面提到的)适配到 Android。请参阅如何使用 ThreeTenABP……。

https://i.stack.imgur.com/Sksw9.png

ThreeTen-Extra 项目使用其他类扩展 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在此处找到一些有用的类,例如 IntervalYearWeekYearQuartermore


“虽然您应该避免使用旧的日期时间类,但在使用现有代码时可能会被迫这样做。如果是这样,您可以转换为 java.time 或从 java.time 转换。”实际上,没有。这和 Date.valueOf() 实际上在 JDBC/Java7 范例中不可用。
@sf_jeff Java 7 支持包含在我的答案末尾的项目符号中:在哪里获取 java.time 类?
@Brain 重读 Convert to ... & 从...转换部分。要与尚未更新到 java.time 的旧代码进行互操作,请在 java.time 中执行您的业务逻辑。在现代与现代之间转换的边缘通过调用添加到旧类的新方法来遗留类型。对于 java.sql.Date,请参阅 toLocalDatevalueOf( LocalDate ) 方法。永远不要使用旧类编写新代码。
我否决了这个答案,但不是因为它不正确。 OP 询问如何做到这一点,而不是威胁使用旧日期对象或是否有更好/更新的方法。据 Basil 所知,OP 仅限于较旧版本的 java 或仅允许这两种类型的库,yada yada yada。
@dnebing 没有恐吓的意图。您可能没有意识到遗留的日期时间类有多么糟糕。 Sun、甲骨文和几年前,JCP 社区都放弃了这些课程,一致采用了 JSR 310java.time 类与 Java 8 及更高版本捆绑在一起。所有遗留类都带有用于在遗留对象和现代对象之间来回转换的新方法。后向端口可用于 Java 6 & 7、并行API。该后端端口也配备了转换方法。所以真的没有理由不使用java.time
m
mauretto

对于其他答案,您可能会遇到时间信息问题(将日期与意外结果进行比较!)

我建议:

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

如果他将 java.sql.Date 用于数据库中的 Date 列,则该时间信息将被截断。在我看来,您过度设计了解决方案。
是的,也许我做到了。我有时需要将 java.sql.Data 与当前日期进行比较,恕我直言,这是最好的方法。我希望它可以帮助。
仅供参考,非常麻烦的旧日期时间类(例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat)现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代。见Tutorial by Oracle
当然,这个话题大约是 10 年前,在 Java 8 之前。
M
Mr. Polywhirl

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

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

S
Sébastien Temprado

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

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

如需更多信息,您可以查看this question


j
jack jay

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

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

其中pickDate 是JXDatePicker 的对象


T
Tanmay kumar shaw

此函数将从 java 日期对象返回转换后的 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;
    }

h
hackfield

首先格式化您的 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);

K
Kishan Bheemajiyani

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

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)

P
PKSawmy

我是一个新手:经过多次运行这个工作。想法可能有用

     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)现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代。见Tutorial by Oracle
D
Donovan Thomson

比较 2 个日期的方法(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;
}

k
kapil das

试试这个

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

T
Tom

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

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+"');

这似乎与一年前发布的 this answer 基本相同。
t
tcooc

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

DateFormat fm= new SimpleDateFormatter();

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

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

然后它会解析你的日期


E
Emmanuel Angelo.R

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

DateUtilities.convertUtilDateToSql(java.util.Date)

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

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

java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(utilDate);


B
Benjamin Ndugga

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

所以我使用 DateFormatter 类对其进行格式化,然后在 sql 语句或准备好的语句中将其设置为字符串

这是代码说明:

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语句中传递这个日期


欢迎来到stackoverflow,我对您的回答有一些评论。问题是“如何将 java.util.Date 转换为 java.sql.Date”。您粘贴的代码将 java.util.Date 格式化为 yyyy-MM-dd。这实际上在这种情况下使用有限,因为您应该将 java.sql.Date 直接传递给 jdbc 驱动程序,而不是将其作为字符串传递。