Choosing between java.util.Date or java.sql.Date - java

Should I use java.util.Date or java.sql.Date?
I have a VisualFox database and I have retrieved the entities with the IntelliJ Idea wizard using an appropiate jdbc type 4 driver.
The ide (or the driver) has created the date fields as Timestamp. However, the date fields are not timestamps but Date fields, they store year, month and day only.
So I wonder if I should switch to java.util.Date or java.sql.Date. At first glance I thought that java.sql.Date should be the appropiate one, but it has many methods declared as deprecated.

tl;dr
Should I use java.util.Date or java.sql.Date?
Neither.
Both are obsolete as of JDBC 4.2 and later. Use java.time classes instead.
date-only valueFor a database type akin to SQL-standard DATE, use java.time.LocalDate.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
myPreparedStatement.setObject( ld , … ) ;
date with time-of-day in UTC valueFor a database type akin to SQL-standard TIMESTAMP WITH TIME ZONE, use java.time.Instant.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
myPreparedStatement.setObject( instant , … ) ;
Details
The question and other answers seem to be over-thinking the issue. A java.sql.Date is merely a java.util.Date with its time set to 00:00:00.
From the java.sql.Date doc (italicized text is mine)…
Class Date
java.lang.Object
    java.util.Date        ← Inherits from j.u.Date
        java.sql.Date
…
A thin wrapper around a millisecond value that allows JDBC to identify this as an SQL DATE value. A milliseconds value represents the number of milliseconds that have passed since January 1, 1970 00:00:00.000 GMT.  ← Time-of-day set to Zero, midnight GMT/UTC
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
Date-Only versus Date-Time
The core problem is:
SQLIn SQL, the DATE data type stores a date-only, without a time-of-day.
JAVAIn the badly designed date-time library bundled with the early versions of Java, they failed to include a class to represent a date-only.
Instead of creating a date-only class, the Java team made a terrible hack. They took their date-time class (the misnamed java.util.Date class, containing both date and time) and extended it to have an instance set its time-of-day to midnight UTC, 00:00:00. That hack, that subclass of j.u.Date, is java.sql.Date.
All this hacking, poor design, and misnaming has made a confusing mess.
Which To Use
So when to use which? Simple, after cutting through the confusion.
When reading or writing to a database’s date-only column, use java.sql.Date as it clumsily tries to mask its time-of-day.
Everywhere else in Java, where you need a time-of-day along with your date, use java.util.Date.
When you have a java.sql.Date in hand but need a java.util.Date, simply pass the java.sql.Date. As a subclass, a java.sql.Date is a java.util.Date.
Even Better
In modern Java, you now have a choice of decent date-time libraries to supplant the old and notoriously troublesome java.util.Date, Calendar, SimpleTextFormat, and java.sql.Date classes bundled with Java. The main choices are:
Joda-Time
java.time(inspired by Joda-Time, defined by JSR 310, bundled with Java 8, extended by the ThreeTen-Extra project)
Both offer a LocalDate class to represent a date only, with no time-of-day and no time zone.
A JDBC driver updated to JDBC 4.2 or later can be used to directly exchange java.time objects with the database. Then we can completely abandon the ugly mess that is the date-time classes in the java.util.* and java.sql.* packages.
setObject | getObject
This article published by Oracle explains that the JDBC in Java 8 has been updated transparently to map a SQL DATE value to the new java.time.LocalDate type if you call getObject and setObject methods.
In obtuse language, the bottom of the JDBC 4.2 update spec confirms that article, with new mappings added to the getObject and setObject methods.
myPreparedStatement.setObject( … , myLocalDate ) ;
…and…
LocalDate myLocalDate = myResultSet.getObject( … , LocalDate.class ) ;
Convert
The spec also says new methods have been added to the java.sql.Date class to convert back and forth to java.time.LocalDate.
public java.time.instant toInstant()
public java.time.LocalDate toLocalDate()
public static java.sql.Date valueOf(java.time.LocalDate)
Time Zone
The old java.util.Date, java.sql.Date, and java.sql.Timestamp are always in UTC. The first two (at least) have a time zone buried deep in their source code but is used only under-the-surface such as the equals method, and has no getter/setter.
More confusingly, their toString methods apply the JVM’s current default time zone. So to the naïve programmer it seems like they have a time zone but they do not.
Both the buried time zone and the toString behavior are two of many reasons to avoid these troublesome old legacy classes.
Write your business logic using java.time (Java 8 and later). Where java.time lacks, use Joda-Time. Both java.time and Joda-Time have convenient methods for going back and forth with the old classes where need be.
Replacements:
java.util.Date is replaced by java.time.Instant
java.sql.Timestamp is replaced by java.time.Instant
java.sql.Date is replaced by java.time.LocalDate.
java.sql.Time is replaced by java.time.LocalTime.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
All three java.time.Local… classes are all lacking any concept of time zone or offset-from-UTC.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Well, according to this article you can use javax.sql.Date without #Temporal annotation which can save some coding from you. However java.util.Date is easier to use across your whole application.
So I would use
#Column(name = "date")
#Temporal(TemporalType.DATE)
private java.util.Date date;

In general, I find it advisable to use the java.util.Date, since you can use it anywhere in your program without either converting the type or polluting your application with SQL-specific code.
I am not aware of a scenario where 'java.sql.Date' would be a better fit.

According to Java doc, it is suggested to use appropriate Date type as per underlying database.
However, with Java 8, a rich set of classes under java.time package have been provided and it must be used if application is written with Java 8.
The class javaxjava.sql.Date extends java.util.Date with minor changes for miliseconds container so that it can support the Database DATE type effectively. This, we can save the #Temporal annotation typing from entity class.
However, java.util.Date could be used for better scalability in entire application so that it can be easily used to store time along with date.

Related

Get Date from a DataObject (SDO) without losing the hour (JAVA)

I'm trying to get a date from a DataObject (Service Date Object (SDO)) that comes to me as an input and insert it into an Oracle database. The problem has been that the Date I get does not seem to have the introduced hour.
I am using the setDate() method from DataObject with the following value: 2019-05-22T13:30:00Z.
For some reason, when using getDate() what is returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I'm not sure if it's due to the input format or something related to the Date class from java.utils.
An easy solution would be to pass it as String and convert it into Date using a format but I would like to save this intermediate step.
java.util.Date versus java.sql.Date
Your Question does not provide enough detail to know for sure, but I can take an educated guess.
returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I suspect your code calling setDate and/or getDate is using a java.sql.Date object rather than a java.util.Date object.
➥ Check your import statements. If you used the wrong class by accident, that would explain the time-of-day getting set to 00:00.
java.util.Date represents a moment in UTC (a date, a time-of-day, and an offset-from-UTC of zero hours-minutes-seconds).
java.sql.Date pretends to represent a date-only, without a time-of-day and without a time zone or offset-from-UTC. Actually does contain a time-of-day and offset, but tries to adjust the time to 00:00:00.0 as part of the pretense.
Confusing? Yes. These old date-time classes from the earliest days of Java are a bloody awful mess, built by people who did not understand the complexities of date-time handling. Avoid these legacy date-time classes!
These legacy classes were supplanted years ago by the modern java.time classes defined in JSR 310. Try to do all your work in java.time. When interoperating with old code such as SDO that is not yet updated for java.time, call on new conversion methods added to the old classes.
The modern replacement of a java.util.Date is java.time.Instant. Both represents a moment in UTC, though Instant has a finer resolution of nanoseconds versus milliseconds.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Convert from modern class to legacy class. Beware of data-loss: Any microseconds or nanoseconds in the fractional second are truncated to milliseconds (as noted above).
java.util.Date d = java.util.Date.from( instant ) ; // Convert from modern to legacy. Truncates any microseconds or nanoseconds.
Pass to your SDO object.
mySdoDataObject.setDate( d ) ;
Going the other direction, retrieve the legacy java.util.Date object and immediately convert to an Instant.
Instant instant = mySdoDataObject.getDate().toInstant() ;
To see that same moment through the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
An easy solution would be to pass it as String
No! Use smart objects, not dumb strings. We have the industry-leading date-time library built into Java, so use it.
Database
As of JDBC 4.2, we can directly exchange java.time objects with the database.
Your JDBC driver may optionally handle Instant. If not, convert to OffsetDateTime.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

What is difference between java.utill.Time and java.sql.time [duplicate]

java.util.Date vs java.sql.Date: when to use which and why?
Congratulations, you've hit my favorite pet peeve with JDBC: Date class handling.
Basically databases usually support at least three forms of datetime fields which are date, time and timestamp. Each of these have a corresponding class in JDBC and each of them extend java.util.Date. Quick semantics of each of these three are the following:
java.sql.Date corresponds to SQL DATE which means it stores years, months and days while hour, minute, second and millisecond are ignored. Additionally sql.Date isn't tied to timezones.
java.sql.Time corresponds to SQL TIME and as should be obvious, only contains information about hour, minutes, seconds and milliseconds.
java.sql.Timestamp corresponds to SQL TIMESTAMP which is exact date to the nanosecond (note that util.Date only supports milliseconds!) with customizable precision.
One of the most common bugs when using JDBC drivers in relation to these three types is that the types are handled incorrectly. This means that sql.Date is timezone specific, sql.Time contains current year, month and day et cetera et cetera.
Finally: Which one to use?
Depends on the SQL type of the field, really. PreparedStatement has setters for all three values, #setDate() being the one for sql.Date, #setTime() for sql.Time and #setTimestamp() for sql.Timestamp.
Do note that if you use ps.setObject(fieldIndex, utilDateObject); you can actually give a normal util.Date to most JDBC drivers which will happily devour it as if it was of the correct type but when you request the data afterwards, you may notice that you're actually missing stuff.
I'm really saying that none of the Dates should be used at all.
What I am saying that save the milliseconds/nanoseconds as plain longs and convert them to whatever objects you are using (obligatory joda-time plug). One hacky way which can be done is to store the date component as one long and time component as another, for example right now would be 20100221 and 154536123. These magic numbers can be used in SQL queries and will be portable from database to another and will let you avoid this part of JDBC/Java Date API:s entirely.
LATE EDIT: Starting with Java 8 you should use neither java.util.Date nor java.sql.Date if you can at all avoid it, and instead prefer using the java.time package (based on Joda) rather than anything else. If you're not on Java 8, here's the original response:
java.sql.Date - when you call methods/constructors of libraries that use it (like JDBC). Not otherwise. You don't want to introduce dependencies to the database libraries for applications/modules that don't explicitly deal with JDBC.
java.util.Date - when using libraries that use it. Otherwise, as little as possible, for several reasons:
It's mutable, which means you have to make a defensive copy of it every time you pass it to or return it from a method.
It doesn't handle dates very well, which backwards people like yours truly, think date handling classes should.
Now, because j.u.D doesn't do it's job very well, the ghastly Calendar classes were introduced. They are also mutable, and awful to work with, and should be avoided if you don't have any choice.
There are better alternatives, like the Joda Time API (which might even make it into Java 7 and become the new official date handling API - a quick search says it won't).
If you feel it's overkill to introduce a new dependency like Joda, longs aren't all that bad to use for timestamp fields in objects, although I myself usually wrap them in j.u.D when passing them around, for type safety and as documentation.
tl;dr
Use neither.
java.time.Instant replaces java.util.Date
java.time.LocalDate replaces java.sql.Date
Neither
java.util.Date vs java.sql.Date: when to use which and why?
Both of these classes are terrible, flawed in design and in implementation. Avoid like the Plague Coronavirus.
Instead use java.time classes, defined in in JSR 310. These classes are an industry-leading framework for working with date-time handling. These supplant entirely the bloody awful legacy classes such as Date, Calendar, SimpleDateFormat, and such.
java.util.Date
The first, java.util.Date is meant to represent a moment in UTC, meaning an offset from UTC of zero hours-minutes-seconds.
java.time.Instant
Now replaced by java.time.Instant.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
java.time.OffsetDateTime
Instant is the basic building-block class of java.time. For more flexibility, use OffsetDateTime set to ZoneOffset.UTC for the same purpose: representing a moment in UTC.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
You can send this object to a database by using PreparedStatement::setObject with JDBC 4.2 or later.
myPreparedStatement.setObject( … , odt ) ;
Retrieve.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
java.sql.Date
The java.sql.Date class is also terrible and obsolete.
This class is meant to represent a date only, without a time-of-day and without a time zone. Unfortunately, in a terrible hack of a design, this class inherits from java.util.Date which represents a moment (a date with time-of-day in UTC). So this class is merely pretending to be date-only, while actually carrying a time-of-day and implicit offset of UTC. This causes so much confusion. Never use this class.
java.time.LocalDate
Instead, use java.time.LocalDate to track just a date (year, month, day-of-month) without any time-of-day nor any time zone or offset.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate ld = LocalDate.now( z ) ; // Capture the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
Send to the database.
myPreparedStatement.setObject( … , ld ) ;
Retrieve.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The only time to use java.sql.Date is in a PreparedStatement.setDate. Otherwise, use java.util.Date. It's telling that ResultSet.getDate returns a java.sql.Date but it can be assigned directly to a java.util.Date.
I had the same issue, the easiest way i found to insert the current date into a prepared statement is this one:
preparedStatement.setDate(1, new java.sql.Date(new java.util.Date().getTime()));
The java.util.Date class in Java represents a particular moment in time (e,.g., 2013 Nov 25 16:30:45 down to milliseconds), but the DATE data type in the DB represents a date only (e.g., 2013 Nov 25). To prevent you from providing a java.util.Date object to the DB by mistake, Java doesn’t allow you to set a SQL parameter to java.util.Date directly:
PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, d); //will not work
But it still allows you to do that by force/intention (then hours and minutes will be ignored by the DB driver). This is done with the java.sql.Date class:
PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, new java.sql.Date(d.getTime())); //will work
A java.sql.Date object can store a moment in time (so that it’s easy to construct from a java.util.Date) but will throw an exception if you try to ask it for the hours (to enforce its concept of being a date only). The DB driver is expected to recognize this class and just use 0 for the hours. Try this:
public static void main(String[] args) {
java.util.Date d1 = new java.util.Date(12345);//ms since 1970 Jan 1 midnight
java.sql.Date d2 = new java.sql.Date(12345);
System.out.println(d1.getHours());
System.out.println(d2.getHours());
}
java.util.Date represents a specific instant in time with millisecond precision. It represents both date and time information without timezone. The java.util.Date class implements Serializable, Cloneable and Comparable interface. It is inherited by java.sql.Date, java.sql.Time and java.sql.Timestamp interfaces.
java.sql.Date extends java.util.Date class which represents date without time information and it should be used only when dealing with databases. To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
It inherits all public methods of java.util.Date such as getHours(), getMinutes(), getSeconds(), setHours(), setMinutes(), setSeconds(). As java.sql.Date does not store the time information, it override all the time operations from java.util.Dateand all of these methods throw java.lang.IllegalArgumentException if invoked as evident from their implementation details.

Timestamp.from not heeding timezone from Instant

When I try to convert a ZonedDateTime to a Timestamp everything is fine until I call Timestamp.from() in the following code:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.minusSeconds(currentTimeUTC.getSecond());
currentTimeUTC = currentTimeUTC.minusNanos(currentTimeUTC.getNano());
return Timestamp.from(currentTimeUTC.toInstant());
ZonedDateTime.now(ZoneOffset.UTC); -> 2018-04-26T12:31Z
currentTimeUTC.toInstant() -> 2018-04-26T12:31:00Z
Timestamp.from(currentTimeUTC.toInstant()) -> 2018-04-26 14:31:00.0
// (with Timezone of Europe/Berlin, which is currently +2)
Why is Timestamp.from() not heeding the timezone set in the instant?
The Instant class doesn't have a timezone, it just has the values of seconds and nanoseconds since unix epoch. A Timestamp also represents that (a count from epoch).
why is the debugger displaying this with a Z behind it?
The problem is in the toString methods:
Instant.toString() converts the seconds and nanoseconds values to the corresponding date/time in UTC - hence the "Z" in the end - and I believe it was made like that for convenience (to make the API more "developer-friendly").
The javadoc for toString says:
A string representation of this instant using ISO-8601 representation.
The format used is the same as DateTimeFormatter.ISO_INSTANT.
And if we take a look at DateTimeFormatter.ISO_INSTANT javadoc:
The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'
As debuggers usually uses the toString method to display variables values, that explains why you see the Instant with "Z" in the end, instead of the seconds/nanoseconds values.
On the other hand, Timestamp.toString uses the JVM default timezone to convert the seconds/nanos values to a date/time string.
But the values of both Instant and Timestamp are the same. You can check that by calling the methods Instant.toEpochMilli and Timestamp.getTime, both will return the same value.
Note: instead of calling minusSeconds and minusNanos, you could use the truncatedTo method:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.truncatedTo(ChronoUnit.MINUTES);
This will set all fields smaller than ChronoUnit.MINUTES (in this case, the seconds and nanoseconds) to zero.
You could also use withSecond(0) and withNano(0), but in this case, I think truncatedTo is better and more straight to the point.
Note2: the java.time API's creator also made a backport for Java 6 and 7, and in the project's github issues you can see a comment about the behaviour of Instant.toString. The relevant part to this question:
If we were really hard line, the toString of an Instant would simply be the number of seconds from 1970-01-01Z. We chose not to do that, and output a more friendly toString to aid developers
That reinforces my view that the toString method was designed like this for convenience and ease to use.
Instant does not hold the Timezone information. It only holds the seconds and nanos.
To when you convert your ZonedDateTime into an Instant the information is lost.
When converting into Timestamp then the Timestamp will hold the default Timezone, which is, in your case, Europe/Berlin.
tl;dr
You are being confused by the unfortunate behavior of Timestamp::toString to apply the JVM’s current default time zone to the objects internal UTC value.
➡ Use Instant, never Timestamp.
A String such as 2018-04-26T12:31Z is in standard ISO 8601 format, with the Z being short for Zulu and meaning UTC.
Your entire block of code can be replaced with:
Instant.now()
…such as:
myPreparedStatement.setObject( … , Instant.now() ) ;
Details
The Answer by wowxts is correct. Instant is always in UTC, as is Timestamp, yet Timestamp::toString applies a time zone. This behavior is one of many poor design choices in those troubled legacy classes.
I'll add some other thoughts.
Use Instant for UTC
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
While technically correct, this line is semantically wrong. If you want to represent a moment in UTC, use Instant class. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Avoid legacy Timestamp class
Timestamp.from(currentTimeUTC.toInstant());
While technically correct, using my suggest above, that would be:
Timestamp.from( instant ); // Convert from modern *java.time* class to troublesome legacy date-time class using new method added to the old class.
Nothing is lost going between Instant and Timestamp, as both represent a moment in UTC with a resolution of nanoseconds. However…
No need to be using java.sql.Timestamp at all! That class is part of the troublesome old date-time classes that are now legacy. They were supplanted entirely by the java.time classes defined by JSR 310. Timestamp is replaced by Instant.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
Insert/Update.
myPreparedStatement.setObject( … , instant ) ;
Retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

SQL database (JDBC): A column of type date only stores date values and not time values

I have a database like this where lastEdited is a date field.
I connected this database to a Java web application by using "RESTFUL web-services from database"
This automatically generated a class called ThreadChat for my THREADCHAT column. Given here is the getter and setter for the lastEdited part.
lastEdited is a java.util.Date object.
public Date getLastedited() {
return lastedited;
}
public void setLastedited(Date lastedited) {
this.lastedited = lastedited;
}
Here, I am creating a new ThreadChat object and adding the data to the database. Argument for lastEdited is a java.util.Date object.
ThreadChat thread = new ThreadChat(threadName, new Date(), loginIdInt);
threadChatFacadeREST.create(thread);
This would update the table like this.
This method returns all the records in the THREADCHAT table.
List<ThreadChat> list = getAllThreads();
However, getLastEdited() returns a XMLGregorianCalender object instead of a Date object as in the getter method above.
If I print this object to the console, the date part is there but I get 00:00 for the minutes and hours part every time.
2018-04-10T00:00:00+05:30
How do I store Date + Time in a JDBC database and retrieve both?
The type of your field in your database is DATE so DATE only stores YYYY-MM-DD.
If you want to store also the time you must change the type of your field in your database to DATETIME. The representation of this is: YYYY-MM-DD HH:MI:SS
More information in: https://www.w3schools.com/sql/sql_datatypes.asp
tl;dr
You are using a date-only type to hold a date-time value – trying to fit a square peg into a round hole.
How do I store Date + Time in a JDBC database and retrieve both?
To store a moment, a date-time value, use a date-time type:
TIMESTAMP WITH TIME ZONE in your database.
Instant in Java.
You are using terribly confusing legacy classes. Use only java.time classes instead.
Databases vary
Databases vary widely in their date-time data types and their behavior. You do not specify your database, so we can only guess or abide by the SQL standard.
The SQL standard barely touches on the subject of date-time handling, unfortunately. The standard briefly defines:
DATE as a date-only value without time-of-day.
A TIMESTAMP WITHOUT TIME ZONE is a date and a time-of-day, but lacks any concept of time zone or offset-from-UTC, so it does not represent actual moments.
For actual moments, use TIMESTAMP WITH TIME ZONE. That type name can be misleading as some implementations such as Postgres do not store a zone with the value, but instead use any passed zone information to adjust into a UTC value for storage.
java.time
You are using terrible old date-time classes from the earliest versions of Java. Those were supplanted in Java 8 and later by the java.time classes. Never use Date or Calendar again.
Generally best to think, work, store, log, and exchange date-time values in UTC unless specifically required by the business logic or user-interface. So generally you should focus on the Instant class. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). This class replaces java.util.Date.
Capture the current moment in UTC.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Store this Instant in a database column of SQL-standard type TIMESTAMP WITH TIME ZONE or whatever is akin to that in your particular database.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
myPreparedStatement.setObject( … , instant ) ;
Retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Converting
If handed an obsolete XMLGregorianCalendar, immediately convert into java.time ZonedDateTime by way of the obsolete GregorianCalendar class.
ZonedDateTime zdt = myXmlGregCal.toGregorianCalendar().toZonedDateTime() ; // Convert from legacy classes to modern java.time class.
If you want to see that same moment in UTC rather than the wall-clock time used by the people of that particular region (time zone), extract an Instant.
Instant instant = zdt.toInstant() ; // Adjust from zoned moment to UTC. Same moment, same point on the timeline, different wall-clock time.
If you must inter-operate with old code not yet updated to java.time, you can convert back and forth. Tip: Try to stay within java.time as much as possible. The legacy classes are an awful mess of poor design.
java.util.Date myJavaUtilDate = java.util.Date.from( instant ) ;
And, going the other direction.
Instant instant = myJavaUtilDate.toInstant() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
You are looking for a DATA_TYPE TIMESTAMP. You should change your Database if you can.

java sql date time

When I insert a SQL DateTime to the database I get 2007-02-07 12:00:00.00
But I made the Date object like this : 2007-02-07 17:29:46.00
How to get the value of the seconds in the database. It always changes it back to 12:00:00.00
date.setYear(Integer.valueOf(parsedDate[2].replaceAll(" ", "")) - 1900);
date.setMonth(Integer.valueOf(parsedDate[0].replaceAll(" ", "")));
date.setDate(Integer.valueOf(parsedDate[1].replaceAll(" ", "")));
...
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
Should I use any formatters?
java.sql.Date represents a date, not a date and time. From the docs:
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
If you want to store a date and time, you should look for another type - e.g. java.sql.Timestamp. EDIT: That's not suggesting you use a TIMESTAMP column type - as paulsm4 says in the comments, that's a different thing. However, as far as I can see, JDBC only supports:
Date (no, you want a time too)
Time (no, you want a date too)
Timestamp (includes a date and time, but you don't want TIMESTAMP SQL semantics)
I would expect using the Java Timestamp type with a DATETIME column to work, although without the level of precision that Timestamp provides.
EDIT: After a bit more research, it looks like you may want to use the java.sql.Time type, but with special driver parameters - at least if you're using the Microsoft driver. See these docs on configuring JDBC for more information.
tl;dr
You are likely confused by not understanding that java.util.Date is a date-with-time type while its subclass java.sql.Date pretends to be a date-only class but actually has its time-of-day set to zero. Bloody awful design. Avoid both these classes entirely. Use java.time classes only.
For a date-only column in your database, define the column as the SQL-standard DATE type.
myPreparedStatement.setObject(
… ,
LocalDateTime.parse( "2007-02-07 17:29:46.00".replace( " " , "T" ) )
.toLocalDate()
)
java.time
The modern approach uses the java.time classes added to Java 8 and later.
When I insert a SQL DateTime to the database I get 2007-02-07 12:00:00.00
There is no such thing as a SQL-standard type as DateTime, nor any such class in Java. So I do not know your intention there.
As for the input string, 2007-02-07 17:29:46.00, parse that as a LocalDateTime because it lacks any indicator of time zone or offset-from-UTC.
That SQL-style format almost complies with the ISO 8601 standard. To fully comply, replace the SPACE in the middle with a T. The java.time classes use the ISO 8601 formats by default when parsing/generating strings.
String input = "2007-02-07 17:29:46.00".replace( " " , "T" ) ;
Parse.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
A LocalDateTime does not represent a moment, is not a point on the timeline. It represents potential moments along a range of about 26-27 hours.
Standard SQL does offer a data type for such a value, TIMESTAMP WITHOUT TIME ZONE.
Smart objects, not dumb strings
Your entire approach is misguided, wrangling text and using the legacy date-time classes. Instead, exchange java.time objects.
As of JDBC 4.2, you need not ever use the troublesome old java.sql types such as java.sql.Date or java.sql.Timestamp. You can directly exchange java.time objects with your database via setObject/getObject methods.
myPreparedStatement.setObject( … , ldt ) ;
And retrieval.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
If you are trying to work with date-only values, use the SQL-standard type DATE and the Java class LocalDate.
LocalDate ld = ldt.toLocalDate() ;
myPreparedStatement.setObject( … , ld ) ;
How to get the value of the seconds in the database
Not sure what you mean by "value of the seconds".
Perhaps you want a count of seconds from the epoch reference of first moment of 1970 in UTC.
long secondsSinceEpoch = ldt.toEpochSecond() ;
If your goal was merely to instantiate a java.sql.Date, don’t bother. Never use that class again. But, FYI, your specific issue is likely a side-effect of the awful design used for that class. The java.sql.Date class inherits from java.util.Date which is a date-with-time type. The java.sql.Date class pretends to be a date-only value, but actually has its time-of-day set to 00:00:00. Even worse, the documentation tells us to ignore the fact of its being a subclass. Don’t bother trying to understand it; just use java.time instead.
If you are trying to work with the time-of-day alone, extract a LocalTime object.
LocalTime lt = ldt.toLocalTime() ;
If you want to set the time-of-day to zeros, then you likely want a date-only value. If so, use the LocalDate class for a date value without a time-of-day and without a time zone.
LocalDate ld = ldt.toLocalDate() :
If you do want the first moment of the day on that date, call LocalDate::atStartOfDay.
LocalDateTime ldtStart = ldt.toLocalDate().atStartOfDay() ;
BEWARE: If you are trying to track actual moments, specific points on the timeline, then all this code above is wrong. Search Stack Overflow to learn about Instant, ZoneId, and ZonedDateTime classes. Search both Stack Overflow and dba.StackExchange.com to learn about the SQL-standard type TIMESTAMP WITH TIME ZONE.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Categories

Resources