tl; dr
Использование объектов, а не строк, для связи с базой данных.
Использование только java.time классов, никогда java.util.Date
, Calendar
или java.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: ГГГГ-ММ-ДД.
java.time
Вы используете ужасные старые классы, которые были вытеснены несколько лет назадсовременные java.time классы.
LocalDateTime
В вашей входной строке отсутствует индикатор часового пояса или смещения от UTC.Поэтому анализируйте как LocalDateTime
.
. Классы java.time по умолчанию используют стандартный формат ISO 8601 при разборе и генерации строк.Ваша входная строка почти соответствует стандарту.Просто замените ПРОБЕЛ в середине на T
.
String input = "2015-05-12 15:15:24".replace( " " , "T" ) ;
Parse.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
OffsetDateTime
A 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 и выше.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Вы можете обмениваться java.time объектами непосредственно с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и more .