简体   繁体   English

在Java中将字符串日期转换为sql日期格式

[英]converting string date to sql Date format in java

I would like to achieve below: 我想实现以下目标:

I have date in string format as eg "2015-05-12 15:15:24", I would like to convert it to sql date in the format "dd-MMM-yy". 我有字符串格式的日期,例如“ 2015-05-12 15:15:24”,我想将其转换为“ dd-MMM-yy”格式的sql date。 However, this is not working. 但是,这不起作用。 below is the code snippet: 下面是代码片段:

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

The output of the program is : 该程序的输出为:

sqlDate : 2015-05-12 :::::: Date2 : Tue May 12 00:00:00 BST 2015 :::: sqlDate2 2015-05-12 sqlDate:2015-05-12 :::::: Date2:Tue May 12 00:00:00 BST 2015 :::: sqlDate2 2015-05-12

The aim was to get date in the format of 12-May-15 java.sql format, but May is not being translated into alphabet month rather its printed as number. 目的是以15年5月12日java.sql格式获取日期,但是May不会转换为字母月份,而是打印为数字。

am I missing anything. 我错过了什么吗? any help would be appreciated. 任何帮助,将不胜感激。

tl;dr TL;博士

Use objects, not strings, to communicate with database. 使用对象而非字符串与数据库进行通信。

Use only java.time classes, never java.util.Date , Calendar , or java.sql.Date classes. 仅使用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.
)

Details 细节

convert it to sql date in the format "dd-MMM-yy" 将其转换为格式为“ dd-MMM-yy”的sql date

There is no such SQL-standard format. 没有这种SQL标准格式。 SQL-standard format for a date is the same as ISO 8601 standard format: YYYY-MM-DD. 日期的SQL标准格式与ISO 8601标准格式相同:YYYY-MM-DD。

java.time java.time

You are using terrible old classes that were supplanted years ago by the modern java.time classes. 您正在使用可怕的旧类,这些旧类在多年前被现代的java.time类所取代。

LocalDateTime

Your input string lacks any indicator of time zone or offset-from-UTC. 您的输入字符串缺少任何时区指示或UTC偏移量。 So parse as a LocalDateTime . 因此解析为LocalDateTime

The java.time classes use standard ISO 8601 format by default when parsing and generating strings. 解析和生成字符串时,默认情况下java.time类使用标准ISO 8601格式。 Your input string is nearly compliant with the standard. 您的输入字符串几乎符合标准。 Just replace the SPACE in the middle with a T . 只需将中间的SPACE替换为T

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

Parse. 解析。

LocalDateTime ldt = LocalDateTime.parse( input ) ;

OffsetDateTime

A LocalDateTime does not represent a moment. 一个LocalDateTime 不代表时刻。 It represents potential moments along a span of about 26-27 hours, the range of time zones around the globe. 它代表了大约26-27小时(全球时区范围)内的潜在时刻。 If you know the intended time zone, apply a ZoneId to get a ZonedDateTime object. 如果您知道预期的时区,请应用ZoneId以获取ZonedDateTime对象。 If you know only a mere offset rather than a zone, apply a ZoneOffset to get a OffsetDateTime object. 如果仅知道偏移量而不是区域,请应用ZoneOffset以获得OffsetDateTime对象。 I will assume your value is intended to represent a moment in UTC, in other words, an offset-from-UTC of zero. 我将假设您的值旨在表示UTC的时刻,换句话说,与UTC的偏移量为零。

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

Smart objects, not dumb strings 智能对象,而不是哑字符串

You should use class types appropriate to your SQL data types to exchange data with your database. 您应该使用适合您的SQL数据类型的类类型来与数据库交换数据。 Use smart objects, not dumb strings. 使用智能对象,而不是哑字符串。

As of JDBC 4.2, we can directly exchange java.time objects. 从JDBC 4.2开始,我们可以直接交换java.time对象。

myPreparedStatement.setObject( … , odt ) ;

Retrieval. 恢复。

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

LocalDate

You care only about the date, not the time-of-day. 您只关心日期,而不关心时间。 So extract a LocalDate object. 因此,提取一个LocalDate对象。

LocalDate ld = odt.toLocalDate() ;

Submit to your database. 提交到您的数据库。

myPreparedStatement.setObject( … , ld ) ;

Retrieval. 恢复。

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

Complete example 完整的例子

Here is a complete example app, in a single .java . 这是一个完整的示例应用程序,位于单个.java

Using the H2 Database Engine . 使用H2数据库引擎 We specify an in-memory database, never persisted to storage, as this is just a demo. 我们指定一个内存数据库,该数据库永远不会持久存储,因为这只是一个演示。

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 NULL\n" +
            ") ; ";
            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();
        }
    }
}

When run: 运行时:

id: 0a4fd38c-7d4e-4049-bc21-e349582c8bc5 | id:0a4fd38c-7d4e-4049-bc21-e349582c8bc5 | name: whatever | 名称:随便| when: 2015-05-12 时间:2015-05-12


About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 And search Stack Overflow for many examples and explanations. 并在Stack Overflow中搜索许多示例和说明。 Specification is JSR 310 . 规格为JSR 310

You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later. 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 No need for strings, no need for java.sql.* classes. 不需要字符串,不需要java.sql.*类。

Where to obtain the java.time classes? 在哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目为将来可能在java.time中添加内容提供了一个试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

You computed it, but never printed it: 您进行了计算,但从未打印过:

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

You have in your code the date in the format you want, but you are assing into a other object type date . 您的代码中具有所需格式的日期,但您正在使用其他对象类型date。

change this : 改变这个:

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

to this : String dateformat =(changedFormat.format(sqlDate)); 对此: String dateformat =(changedFormat.format(sqlDate));

you can pass the value from the string yo your object date. 您可以从对象日期的字符串yo中传递值。 but if you print the var date you don´t print in the format you want, and this is becouse : 但是,如果您打印var日期,则不会以所需的格式打印,这是因为:

Date does not store any format into itself. 日期本身不会存储任何格式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM