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

标签 java sql database oracle

我想实现以下目标:

我有字符串格式的日期,例如“ 2015-05-12 15:15:24”,
我想将其转换为“ dd-MMM-yy”格式的sql date。
但是,这不起作用。下面是代码片段:

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


该程序的输出为:

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

目的是以15年5月12日java.sql格式获取日期,但是May不会转换为字母月份,而是打印为数字。

我错过了什么吗?任何帮助,将不胜感激。

最佳答案

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


细节


  将其转换为格式为“ dd-MMM-yy”的sql date


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

java.time

您正在使用可怕的旧类,这些旧类在多年前被现代的java.time类所取代。

LocalDateTime

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

解析和生成字符串时,java.time类默认使用标准ISO 8601格式。您的输入字符串几乎符合标准。只需将中间的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 Database Engine。我们指定一个内存数据库,该数据库永远不会持久存储,因为这只是一个演示。

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


运行时:


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




关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

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

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

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

在哪里获取java.time类?


Java SE 8Java SE 9Java SE 10Java SE 11和更高版本-具有捆绑实现的标准Java API的一部分。


Java 9添加了一些次要功能和修复。

Java SE 6Java SE 7


大多数java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

Android


更高版本的Android捆绑了java.time类的实现。
对于较早的Android(<26),ThreeTenABP项目改编为ThreeTen-Backport(如上所述)。请参见How to use ThreeTenABP…



ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

关于java - 在Java中将字符串日期转换为sql日期格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52487581/

相关文章:

sql - ROW_NUMBER 不带 ORDER BY

java - 使用 Hibernate 备份和恢复数据库

php - 为每个帐户或几个大表动态创建 mysql 表

wpf - 设置新行的内容 Datagrid

java - 在没有反应堆的情况下按顺序清理/安装多个maven项目

java - 当我从一个 fragment 滑动到另一个 fragment 时如何做一个事件

java - 在 Spring 验证注释中使用消息参数

java - 如何删除所有不必要的分号(在 block 的末尾)?

php - MySQL外域搜索

SQL Server 2016 Developer 版本无法连接到 (LocalDB)\MSSQLLocalDB