在java中将字符串日期转换为sqlDate格式



我想实现以下目标:

我有字符串格式的日期,例如"2015-05-12 15:15:24",我想将其转换为sql日期,格式为"dd MMM yy"。然而,这并不奏效。下面是代码片段:

String rawDate="2015-05-12 15:15:24";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date =format.parse(rawDate);
Date sqlDate = new java.sql.Date(date.getTime());
SimpleDateFormat changedFormat = new SimpleDateFormat("dd-MMM-yy");
Date date2=changedFormat.parse(changedFormat.format(sqlDate));
Date sqlDate2 = new java.sql.Date(date2.getTime());
System.out.println("sqlDate : "+sqlDate +"  ::::::   Date2 : "+date2+"  :::: sqlDate2  "+sqlDate2);ow here is the Test : "+sqlDate2);

程序的输出为:

sql日期:2015-05-12:::日期2:5月12日星期二00:00:00 BST 2015:::sqlDate2 2015-05-12

其目的是以2015年5月12日java.sql格式获取日期,但5月并没有被翻译成字母月,而是被打印成数字。

我有什么遗漏吗。任何帮助都将不胜感激。

tl;dr

使用对象而不是字符串与数据库通信。

只使用java.time类,不要使用java.util.DateCalendarjava.sql.Date类。

myPreparedStatement.setObject(                      // Use smart objects, not dumb strings.
… ,                                             // Specify which placeholder `?` in you SQL.
LocalDateTime.parse(                            // Parse input string lacking any zone or offset as a `LocalDateTime` object. *NOT* a moment, just a vague idea about *potential* moments.
"2015-05-12 15:15:24".replace( " " , "T" )  // Alter your input string to comply with ISO 8601 standard format, with `T` in the middle.
)                                               // Returns a `LocalDateTime` object.
.atOffset(                                      // Apply an offset-from-UTC to determine a moment, a specific point on the timeline.
ZoneOffset.UTC                              // Apply UTC if the input string was intended to be a moment in UTC.
)                                               // Returns a `OffsetDateTime` object.
.toLocalDate()                                  // Extract a date-only value, a `LocalDate` object from the date-with-time `OffsetDateTime` object.
)

详细信息

将其转换为sql日期,格式为"dd MMM yy">

没有这样的SQL标准格式。日期的SQL标准格式与ISO 8601标准格式相同:YYYY-MM-DD。

java.time

您使用的是糟糕的旧类,这些类在几年前被现代的java.time类所取代。

LocalDateTime

您的输入字符串缺少任何时区或UTC偏移量的指示符。因此解析为LocalDateTime

在解析和生成字符串时,java.time类默认使用标准ISO8601格式。您的输入字符串几乎符合标准。只需将中间的SPACE替换为T即可。

String input =  "2015-05-12 15:15:24".replace( " " , "T" ) ;

分析。

LocalDateTime ldt = LocalDateTime.parse( input ) ;

OffsetDateTime

LocalDateTime不代表一个时刻。它代表了全球时区范围内26-27小时的潜在时刻。如果您知道预定的时区,请应用ZoneId来获得ZonedDateTime对象。如果只知道一个偏移而不知道一个区域,则应用ZoneOffset来获得OffsetDateTime对象。我假设您的值旨在表示UTC中的一个时刻,换句话说,从UTC偏移零。

OffsetDateTime odt = ldt.atOffset( Offset.UTC ) ;

智能对象,而不是愚蠢的字符串

您应该使用适合SQL数据类型的类类型来与数据库交换数据。使用智能对象,而不是愚蠢的字符串。

从JDBC 4.2开始,我们可以直接交换java.time对象。

myPreparedStatement.setObject( … , odt ) ;

检索。

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

LocalDate

你只在乎日期,不在乎一天中的时间。因此提取一个LocalDate对象。

LocalDate ld = odt.toLocalDate() ;

提交到您的数据库。

myPreparedStatement.setObject( … , ld ) ;

检索。

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

完整示例

以下是一个完整的示例应用程序,位于单个.java中。

使用H2数据库引擎。我们指定了一个内存中的数据库,从不持久化到存储中,因为这只是一个演示。

package com.basilbourque.example;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;
public class DateIntoDatabase {
public static void main ( String[] args ) {
DateIntoDatabase app = new DateIntoDatabase();
app.doIt();
}
private void doIt () {
try {
Class.forName( "org.h2.Driver" );
} catch ( ClassNotFoundException e ) {
e.printStackTrace();
}
try (
Connection conn = DriverManager.getConnection( "jdbc:h2:mem:date_into_db_example_" ) ;
Statement stmt = conn.createStatement() ;
) {
String sql = "CREATE TABLE event_ (n" +
"  id_ UUID DEFAULT random_uuid() PRIMARY KEY ,n" +
"  name_ VARCHAR NOT NULL ,n" +
"  when_ DATE NOT NULLn" +
") ; ";
System.out.println( sql );
stmt.execute( sql );
// Insert row.
sql = "INSERT INTO event_ ( name_ , when_ ) " + "VALUES ( ? , ? ) ;";
try ( PreparedStatement preparedStatement = conn.prepareStatement( sql ) ; ) {
String name = "whatever";
LocalDate ld = LocalDateTime.parse( "2015-05-12 15:15:24".replace( " " , "T" ) ).atOffset( ZoneOffset.UTC ).toLocalDate();
preparedStatement.setString( 1 , name );
preparedStatement.setObject( 2 , ld );
preparedStatement.executeUpdate();
}
// Query all.
sql = "SELECT * FROM event_ ;";
try ( ResultSet rs = stmt.executeQuery( sql ) ; ) {
while ( rs.next() ) {
//Retrieve by column name
UUID id = ( UUID ) rs.getObject( "id_" );  // Cast the `Object` object to UUID if your driver does not support JDBC 4.2 and its ability to pass the expected return type for type-safety.
String name = rs.getString( "name_" );
LocalDate ld = rs.getObject( "when_" , LocalDate.class );
//Display values
System.out.println( "id: " + id + " | name: " + name + " | when: " + ld );
}
}
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}

运行时:

id:0a4fd38c-7d4e-4049-bc21-e349582c8bc5|名称:任意|时间:2015-05-12


关于java.time

java.time框架构建在Java8及更高版本中。这些类取代了诸如java.util.DateCalendar和&CCD_ 18。

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

要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和解释。规范是JSR310。

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

从哪里获得java.time类?

  • Java SE 8Java SE 9Java SE 10爪哇SE 11及更高版本-标准Java API的一部分,带有捆绑实现。
    • Java9添加了一些小功能和修复程序
  • Java SE 6Java SE 7
    • 大部分Java.time功能都是回移植到Java 6&7英寸ThreeTen背包
  • Android
    • java.time类的Android捆绑包的后续版本
    • 对于早期的Android(<26),ThreeTenABP项目适用于ThreeTen Backport(如上所述)。请参阅如何使用ThreeTenABP…

ThreeTen Extra项目通过附加类扩展java.time。这个项目是将来可能添加到java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等等。

您计算过它,但从未打印过:

String rawDate = "2015-05-12 15:15:24";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = format.parse(rawDate);
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
SimpleDateFormat changedFormat = new SimpleDateFormat("dd-MMM-yy");
System.out.println("Formatted Date: " + changedFormat.format(sqlDate));

您的代码中有您想要的格式的日期,但您正在使用其他对象类型的日期。

更改此项:

Date date2=changedFormat.parse(changedFormat.format(sqlDate));
Date sqlDate2 = new java.sql.Date(date2.getTime());

到此:String dateformat =(changedFormat.format(sqlDate));

您可以将字符串中的值传递给对象日期。但如果你打印var日期,你就不会以你想要的格式打印,这就是:

日期本身不存储任何格式

最新更新