Як конвертувати java.util.Date в java.sql.Date?


453

Я намагаюсь використовувати java.util.Dateяк вхід, а потім створювати з ним запит - тому мені потрібен java.sql.Date.

Я був здивований, виявивши, що не може зробити перетворення неявно або явно - але я навіть не знаю, як би це зробити, оскільки Java API для мене все ще досить новий.


Ви можете знайти подібну проблему тут stackoverflow.com/questions/12131068/…
Lem

Для мене виявилося, що мені не потрібно конвертувати. У import java.sql.*моєму коді був код, який переосмислив java.util.date і, таким чином, спричинив проблеми при призначенні значень дати, які були в порядку з останніми, але не з першими. HTH
HumanInDisguise

1
@DavidAckerman Ви розумієте, що java.util.Date - це дата та час дня, але java.sql.Date - це лише дата без часу? (Насправді є час дня, але це ігнорується, поганий злом дизайну класу) У SQL DATEозначає лише дату.
Василь Бурк

2
Я справді не знав про нюанси ще в09 році, і оскільки це питання настільки популярне, я змінив прийняту відповідь на одну, яка є і більш сучасною і повною. Дякуємо всім за ваш внесок!
Девід Акерман

Відповіді:


89

тл; д-р

Як конвертувати java.util.Date в java.sql.Date?

Не варто. Обидва класи застаріли.

  • Використовуйте класи java.time замість застарілих java.util.Dateта java.sql.Dateз JDBC 4.2 або новіших версій.
  • Перетворити в / з java.time, якщо взаємодія з кодом ще не оновлено до java.time.

Приклад запиту з 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.

Таблиця типів дат і часу на Java (як застаріла, так і сучасна) та в стандарті SQL.

java.time

У Java 8 та пізніших версіях тривожні старі класи дат у часі з ранніми версіями Java були замінені новим пакетом java.time . Дивіться навчальний посібник Oracle . Значна частина функцій була підпорядкована на Java 6 та 7 у ThreeTen-Backport та додатково адаптована до Android у ThreeTenABP .

Тип даних SQL DATE призначається , щоб бути дата-тільки, без часу доби і без часового поясу. У Java ніколи не було саме такого класу † до java.time.LocalDateJava 8. Давайте створимо таке значення, отримавши сьогоднішню дату відповідно до певного часового поясу (часовий пояс важливий для визначення дати як світанку нового дня раніше в Парижі, ніж у Монреалі, для приклад).

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 відповідає специфікації JDBC 4.2 , ви повинні мати змогу пройти LocalDateвік setObjectна а PreparedStatementдля зберігання в поле DATE SQL.

myPreparedStatement.setObject( 1 , localDate );

Так само використовуйте ResultSet::getObjectдля отримання зі стовпця SQL DATE до LocalDateоб’єкта Java . Визначення класу у другому аргументі робить ваш код безпечним для типу .

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ідеєю схожий на a java.util.Date. Але зауважте, що Instantвона має роздільну здатність до наносекунд, а роздільна здатність java.util.Date- лише мілісекунд .

Для перетворення використовуйте нові методи, додані до старих класів. Наприклад, 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 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date, Calendar, і SimpleDateFormat.

Проект Joda-Time , який зараз знаходиться в режимі обслуговування , радить перейти до класів java.time .

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

Ви можете обмінюватися об'єктами java.time безпосередньо зі своєю базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або пізнішої версії. Немає необхідності в струнах, немає потреби в java.sql.*заняттях.

Де отримати класи java.time?

Таблиця, яку бібліотеку java.time використовувати в якій версії Java або Android

The ThreeTen-Extra розширює java.time додатковими класами. Цей проект є передумовою для можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи туттакі якInterval,YearWeek,YearQuarter, і більш .


478

Не звертай уваги....

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


34
Це не явне перетворення! З Javadoc: "Якщо дане значення мілісекунд містить інформацію про час, драйвер встановить часові компоненти на час у часовому поясі за замовчуванням (часовий пояс віртуальної машини Java, що працює у програмі), що відповідає нулю GMT". Тому незалежно від вашого часу на java.util.Date, він буде вставлений як 00:00:00 у стовпець із типом даних, встановленим на DATE.

1
@David Ackerman ..... цей метод повертає epochsecondsтобто мілісекунди після 1,JAN,1970. Але що робити, якщо ми хочемо зберегти дату людини перед цією датою .... або щось на кшталт0000-00-00 as default
Арджун КП

31
У моєму випадку правильною відповіддю є <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code>, оскільки він зберігає поля часу.
Альберто де Паола

2
@ wired00 Так, старі класи з датою в комплекті з ранніми версіями Java - безлад , погано розроблений, включаючи деякі сирі хаки. По можливості намагайтеся використовувати нову рамку java.time в Java 8 та новіших версіях. Ці нові класи витісняють старі. Класи java.time та старі класи мають деякі зручні методи перетворення вперед та назад - корисні, поки ми чекаємо оновлення драйверів JDBC для прямого використання нових типів java.time.
Василь Бурк

1
@ wired00 Дивіться мій новий відповідь на це запитання щодо використання java.time. Також шукайте в StackOverflow ще багато прикладів.
Василь Бурк

39

З іншою відповіддю у вас можуть виникнути проблеми з інформацією про час (порівняйте дати з несподіваними результатами!)

Я пропоную:

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

5
Якщо він використовує java.sql.Date для стовпця Дата в базі даних, ця інформація буде скорочена. Ви переосмислили рішення на мою думку.
darioo

4
Так, можливо, я це і зробив. Мені іноді потрібно порівняти java.sql.Data з поточною датою, і imho це найкращий спосіб. Я сподіваюся, що це може допомогти.
маурето

FYI, жахливі старі класи дату, такі як java.util.Date, java.util.Calendarі java.text.SimpleDateFormatтепер застарілі , витіснені класами java.time, вбудованими в Java 8 та новіших версій. Дивіться Підручник від Oracle .
Василь Бурк

Звичайно, ця тема була близько 10 років тому, pre-java 8.
mauretto

26

Ця функція поверне перетворену дату SQL від об’єкта дати Java.

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

18

Перетворення java.util.Dataна java.sql.Dataвтрату години, хвилини та секунди. Тож якщо це можливо, я пропоную вам скористатися java.sql.Timestampтак:

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

Для отримання додаткової інформації ви можете перевірити це питання .


16

У моєму випадку вибору дати з JXDatePicker (Java-календаря) та зберігання її в базі даних як тип дати SQL, нижче працює чудово.

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

де picDate є об’єктом JXDatePicker


5

Ця функція поверне перетворену дату SQL від об’єкта дати Java.

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

3

Спершу відформатуйте 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);

2

Ось приклад перетворення Util Date на дату Sql, і це один із прикладів того, що я використовую у своєму проекті, може бути корисним і для вас.

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)

2

Я новачок: після багатого бігання навколо цього спрацювало. Думка може бути корисною

     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

FYI, жахливі старі класи дату, такі як java.util.Date, java.util.Calendarі java.text.SimpleDateFormatтепер застарілі , витіснені класами java.time, вбудованими в Java 8 та новіших версій. Дивіться Підручник від Oracle .
Василь Бурк

2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Тут javaDate є примірником java.util.Date


1
Це, схоже, не додає нічого нового порівняно з відповідями Девіда Акермана, четаном та Тамаєм Кумаром Шоу, чи не так?
Оле ВВ

1

Метод порівняння 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;
}

0

спробуйте з цим

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

-1

Я думаю, що найкращий спосіб перетворення:

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

1
Це, по суті, те саме, що ця відповідь, розміщена роком раніше.
Бернхард Баркер

-3

я використовую наступний код, будь ласка, спробуйте його

DateFormat fm= new SimpleDateFormatter();

вкажіть, наприклад, формат потрібної дати, "DD-MM_YYYY"а 'YYYY-mm-dd' потім використовуйте тип даних Java

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

тоді він розбере вашу дату


-3

Ви можете використовувати цей метод для перетворення дати утиліти в дату sql,

DateUtilities.convertUtilDateToSql(java.util.Date)

У стандартній бібліотеці Java немає класу DateUtilities (і я навіть не можу взагалі знайти цей метод десь із швидкого пошуку Google). Якщо це з певної бібліотеки, ви можете сказати стільки і включити посилання на документи.
Бернхард Баркер

-4

Я намагався наступне кодування, яке добре працювало.

java.util.Date utilDate = новий java.util.Date ();
java.sql.Date sqlDate = новий java.sql.Date (utilDate);


-8

Якщо ви користуєтесь Mysql стовпцем дати, може бути передано рядкове зображення цієї дати

тому я використовую клас DateFormatter, щоб відформатувати його, а потім встановити його як String в 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


14
Ласкаво просимо в stackoverflow, у мене є кілька коментарів до вашої відповіді. Питання полягало в тому, як "перетворити java.util.Date в java.sql.Date". Код, який ви вставили, форматує java.util.Дати як yyyy-MM-dd. Це фактично обмежене використання в цьому контексті, оскільки ви повинні передавати java.sql.Date безпосередньо драйверам jdbc, а не робити це як рядок.
jontro
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.