Java mysql jdbc date

How to convert java.util.Date to java.sql.Date — JDBC Example

You often need to convert java.util.Date to java.sql.Date if you are storing dates in a database e.g. SQL SERVER or MySQL. Since JDBC has their own data types for date and time e.g. java.sql.Date , java.sql.Time and java.sql.TimeStamp to match with database date, time and date-time types, you cannot pass a java.util.Date directly. All methods which are supposed to store dates e.g. setDate(paramName, paramValue) expects java.sql.Date, so it becomes essential to know how to convert java.util.Date to java.sql.Date in JDBC. You would be surprised to know that java.sql.Date is a subclass of java.util.Date and all it does is suppress or remove time-related fields from java.util.Date.

It is also a good example of a class which violates Liskov substitution principle, because even though java.sql.Date extends java.util.Date , you cannot pass around it to the method which expect java.util.Date because all time-related methods e.g. getHour() , getMinute() and getSeconds() method throws java.util.NotSupportedException .

I really hope that the JDBC driver could do the translation depending upon the data type of columns and Java developer could just pass the java.util.Date I mean, convert it to java.sql.Date if the column in the table is of type DATE, java.sql.Time if the type of column is TIME and java.sql.Timestamp if the data type of column is DATETIME.

Читайте также:  Python в расширении php

Converting java.util.Date to java.sql.Date — Example

Unfortunately, there is no method like toSQLDate() in java.util.Date class to facilitate conversion between util date and SQL date but you can use getTime() method to extract long millisecond value from java.util.Date and create a new java.sql.Date based on that value as shown below:

Date now = new Date(); java.sql.Date sqlDate = new java.sql.Date(now.getTime());

This is the easiest and right way to convert a java.util.Date to java.sql.Date in Java. To learn more about JDBC and how to write Java application that connects to the database, please see Core Java, Volume II—Advanced Features (10th Edition), one of the best books to learn advanced features of Java programming language.

Things to remember about SQL and Normal Date in Java

1) java.sql.Date mapped to DATE datatype on JDBC i.e. Type.Date, which corresponds to date equivalent in DB side. In SQLSERVER till 2008 it maps to DATETIME and afterward maps to DATE data type.

2) java.sql.Date extends java.util.Date but violets Liskov Substituion Principle.

3) You can convert between java.util.Date and java.sql.Date by using getTime() method.

4) Here is mapping between MySQL date and time types and Java Date types:

How to convert java.util.Date to java.sql.Date with example

That’s all about how to convert java.util.Date to java.sql.Date in Java and JDBC. It’s one of the most useful tips while working in JDBC. You can even create a class like JdbcUtil to host all date and time-related conversion methods like toSQLDate(), toSQLTime(), etc.

  • 10 Examples of Java 8 Date and Time API (tutorial)
  • How do you calculate the difference between two dates in Java? (solution)
  • How to convert a String to Date in Java? (example)
  • How to get a day, month, and year from a Date in Java? (solution)
  • How to convert XMLGregorianCalendar to Date in Java? (solution)
  • How to get the current date with Timezone in Java? (example)
  • 3 ways to compare two dates in Java? (program)
  • How to add days, months, and years from a Date in Java? (solution)
  • The difference between java.sql.Time, java.sql.Timestamp and java.util.Date in Java? (answer)
  • How to increment the date in Java? (solution)
  • How to convert local time to GMT in Java? (answer)
  • How to convert Date to String in Java? (answer)
  • Why should you not use SimpleDateFormat in Java? (answer)

By the way, if you are using Java 8 then consider using LocalDate and LocalTime which are both immutable and thread-safe but yes again converting LocalDate to SQL Date or LocalTime to SQL date is not easy and I will show you how to do it on next article, till then keep learning.

Источник

Работа со временем

Со времен, когда придумали JDBC и стандартизировали его интерфейсы, прошло лет 20, и за это время много чего изменилось.

Во-первых, мир стал глобальным и теперь один сервер может обслуживать пользователей со всего мира. Скорость интернета порешала. Поэтому в SQL был добавлен еще один тип данных для работы со временем. Теперь типы выглядят вот так:

  • DATE – хранит дату: год, месяц, день.
  • TIME – хранит время: часы, минуты, секунды.
  • TIMESTAMP – хранит конкретный момент времени: дата, время и миллисекунды.
  • TIMESTAMP WITH TIME ZONE – TIMESTAMP и временная зона (имя зоны или смещение).

Во-вторых, в Java появился DateTime API для глобальной работы со временем. В нем появились такие классы:

  • Дата и время:
    • LocalDate
    • LocalTime
    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

    Третий интересный момент состоит в том, что очень многим SQL-клиентам хотелось бы получать время с сервера уже в своей локальное зоне . Преобразовывать время на лету конечно можно, но это не удобно, да и ошибки бывают.

    Например, я хочу получить из базы все задания на сегодня. У SQL-сервера есть функция CURDATE() для этого дела. Только вот сервер находится в США, а я – в Японии. И хотелось бы чтобы он мне вернул все записи за “мое сегодня”, а не “его сегодня”.

    В общем, SQL-сервер тоже должен уметь по-умному работать с клиентами в разных временных зонах.

    Современные проблемы требуют современных решений

    В принципе, новые типы из Java DateTime API и типы из SQL можно удобно сопоставлять. Для того чтобы представить тип DATE в Java нужно использовать класс java.time.LocalDate из JDK 8 DateTime API.

    Тип TIME из базы данных можно представить двумя типами из Java: java.time.LocalTime и java.time.OffsetTime . Тоже ничего сложного.

    Конкретный момент времени, представленный типом TIMESTAMP в базе, в Java можно представить 4 типами:

    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

    Ну, и наконец, TIMESTAMP WITH TIME ZONE можно представить двумя типами:

    Так как ты уже знаком с DateTime API, то запомнить это дело тебе труда не составит 🙂

    Запишу в виде таблицы, так будет проще:

    SQL TYPE Java Type
    DATE java.time.LocalDate
    TIME java.time.LocalTime
    java.time.OffsetTime
    TIMESTAMP java.time.Instant
    java.time.LocalDateTime
    java.time.OffsetDateTime
    java.time.ZonedDateTime
    TIMESTAMP WITH TIME ZONE java.time.OffsetDateTime
    java.time.ZonedDateTime

    Получение даты

    У меня для тебя хорошая новость. Первая за долгое время. Мы можем обойти ограничение метода getDate() , который возвращает тип java.sql Date.

    Дело в том, что у объекта ResultSet есть еще один интересный метод — getObject() . Этот метод принимает два параметра: колонку и тип, и возвращает значение колонки, преобразованное к заданному типу. Общий вид метода такой:

     ИмяКласса имя = getObject(column, ИмяКласса);

    И если вы хотите преобразовать тип DATE к типу java.time.LocalDate , то нужно написать что-то типа:

     LocalDate localDate = results.getObject(4, LocalDate.class); 

    А любой TIMESTAMP вообще можно преобразовать к куче типов:

     java.time.Instant instant = results.getObject(9, java.time.Instant.class); java.time.LocalDateTime local = results.getObject(9, java.time. LocalDateTime.class); java.time.OffsetDateTime offset = results.getObject(9, java.time. OffsetDateTime.class); java.time.ZonedDateTime zoned = results.getObject(9, java.time. ZonedDateTime.class); 

    Важно! Этот код не будет работать если у вас устаревший MySQL JDBC Driver . Обрати внимание на версию “mysql-connector-java”, прописанную в твоем pom.xml, или добавленную в Libraries в настройках проекта.

    Кстати, таким же способом можно обойти и невозможность хранить null у примитивных типов. Если колонка таблицы имеет тип INT, то есть пара способов получить из нее null. Смотри пример ниже:

     Integer id1 = results.getObject(8, Integer.class); //так будет работать Integer id2 = results.getObject(8, int.class); //так тоже будет работать int id3 = results.getObject(8, Integer.class); //метод вернет null, JVM кинет NPE int id4 = results.getObject(8, int.class); //метод вернет null, JVM кинет NPE 

    Настройка часового пояса в MySQL

    С MySQL тоже произошло много всего интересного. Как ты знаешь, при создании соединения с MySQL к нему можно добавлять различные параметры:

    mysql://localhost:3306/db_scheme?имя=значение&имя=значение 

    Так вот, для работы с временными зонами в MySQL добавили три параметра. Эти параметры ты можешь передавать, когда устанавливаешь соединение с сервером.

    Ниже я приведу таблицу с ними:

    Параметр Значения Значение по умолчанию
    connectionTimeZone LOCAL | SERVER | user-zone SERVER
    forceConnectionTimeZoneToSession true | false true
    preserveInstants true | false false

    С помощью параметра connectionTimeZone мы выбираем временную зону (часовой пояс), в котором будут выполняться все запросы. С точки зрения клиента, сервер работает в указанной временной зоне.

    Параметр forceConnectionTimeZoneToSession заставляет игнорировать переменную time_zone сессии и заменить ее на connectionTimeZone.

    И наконец параметр preserveInstants управляет преобразование точного-момента-времени между JVM timeZone и connectionTimeZone.

    Самые частые конфигурации такие:

    • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=false — соответствует старому MySQL JDBC драйверу версии 5.1 с параметром useLegacyDatetimeCode=true.
    • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=true — новый режим, обеспечивающий наиболее естественный способ обработки значений даты и времени.
    • connectionTimeZone=SERVER & preserveInstants=true — соответствует старому MySQL JDBC драйверу версии 5.1 с параметром useLegacyDatetimeCode=false.
    • connectionTimeZone=user_defined & preserveInstants=true — помогает преодолеть ситуацию, когда часовой пояс сервера не может быть распознан коннектором, потому что он установлен как общая аббревиатура, такая как CET/CEST.

    Да, даты — тема интересная и проблем с ними много. Как говорится: это конечно страшно, но и я не сыкло! 🙂

    Источник

    How to handle date in JDBC?

    You can insert date values in SQL using the date datatype, The java.sql.Date class maps to the SQL DATE type.

    The PreparedStatement interface provides a method named setDate(). Using this you can insert date into a table. This method accepts two parameters −

    • An integer representing the parameter index of the place holder (?) to which we need to set date value.
    • a Date object representing the date value to be passed. The constructor of java.sql.Date class accepts a variable of long type representing the number of milliseconds from the epoch (standard base time I.e. January 1, 1970, 00:00:00 GMT).

    Example

    Assume we have created a table named Emp in MySQL database with the following description −

    +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | Name | varchar(255) | YES | | NULL | | | DOB | date | YES | | NULL | | | Location | varchar(255) | YES | | NULL | | +----------+--------------+------+-----+---------+-------+

    Following JDBC program inserts records in to this table −

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.sql.Date; public class InsertingDate < public static void main(String args[])throws Exception < //Getting the connection String mysqlUrl = "jdbc:mysql://localhost/sampleDB"; Connection con = DriverManager.getConnection(mysqlUrl, "root", "password"); System.out.println("Connection established. "); //Inserting values to a table String query = "INSERT INTO Emp(Name, DOB, Location) VALUES (?, ?, ?)"; PreparedStatement pstmt = con.prepareStatement(query); pstmt.setString(1, "Amit"); pstmt.setDate(2, new Date(622790105000L)); pstmt.setString(3, "Hyderabad"); pstmt.execute(); pstmt.setString(1, "Sumith"); pstmt.setDate(2, new Date(620611200000L)); pstmt.setString(3, "Vishakhapatnam"); pstmt.execute(); pstmt.setString(1, "Sudha"); pstmt.setDate(2, new Date(336614400000L)); pstmt.setString(3, "Vijayawada"); pstmt.execute(); System.out.println("Records inserted. "); >>

    Output

    Connection established. Records inserted.

    If you verify the table in MySQL database, you can observe the contents of the table as −

    mysql> select * from Emp; +--------+------------+----------------+ | Name | DOB | Location | +--------+------------+----------------+ | Amit | 1989-09-26 | Hyderabad | | Sumith | 2019-03-19 | Vishakhapatnam | | Sudha | 2019-03-19 | Vijayawada | +--------+------------+----------------+ 3 rows in set (0.00 sec)

    Источник

Оцените статью