Как преобразовать java.util.Date в java.sql.Date?


453

Я пытаюсь использовать в java.util.Dateкачестве входных данных, а затем создать запрос с ним - так что мне нужно java.sql.Date.

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


Вы можете найти похожую проблему здесь 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.time вытеснил проблемные старые классы даты и времени, связанные с ранними версиями Java . Смотрите Oracle Tutorial . Большая часть функциональности была перенесена в 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для хранения в поле SQL DATE.

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идее похож на 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 Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в java.sql.*классах.

Где взять классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android

Таблица какой библиотеки java.time использовать с какой версией Java или Android

Проект 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, на которой запущено приложение), что соответствует нулю по Гринвичу». Поэтому независимо от того, какое у вас время на 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 для столбца Date в базе данных, эта информация о времени будет усечена. Вы, по моему мнению, переоценили решение.
darioo

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

К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и более поздние версии . Смотрите Учебник по Oracle .
Василий Бурк

Конечно, эта тема была около 10 лет назад, до
Ява

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 calender) и сохранение ее в базе данных как тип даты SQL, ниже работает нормально.

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

где pickDate является объектом 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 date, и да, это один пример того, что я использую в своем проекте, может быть полезно и вам.

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

К вашему сведению, ужасно неприятные старые классы даты и времени, такие как 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

Метод сравнения двух дат (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 Date как

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

тогда он будет разбирать вашу дату


-3

Вы можете использовать этот метод, чтобы преобразовать дату использования в дату sql,

DateUtilities.convertUtilDateToSql(java.util.Date)

В стандартной библиотеке Java нет класса DateUtilities (и я вообще нигде не могу найти этот метод из быстрого поиска в Google). Если это из конкретной библиотеки, вы можете сказать об этом и включить ссылку на документы.
Бернхард Баркер

-4

Я пытался следующее кодирование, которое работало нормально.

java.util.Date utilDate = new java.util.Date ();
java.sql.Date sqlDate = new java.sql.Date (utilDate);


-8

Если вы используете Mysql, столбцу даты может быть передано строковое представление этой даты.

поэтому я использую класс DateFormatter, чтобы отформатировать его, а затем установить его как строку в выражении SQL или подготовленном утверждении

Вот иллюстрация кода:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

String date = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// затем передаем эту дату в вашем SQL-заявлении


14
Добро пожаловать в stackoverflow, у меня есть несколько комментариев к вашему ответу. Вопрос был «как преобразовать java.util.Date в java.sql.Date». Вставленный вами код форматирует java.util.Date как yyyy-MM-dd. Это на самом деле ограниченное использование в этом контексте, так как вы должны передавать java.sql.Date напрямую драйверам jdbc вместо того, чтобы делать это как строку.
Jontro
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.