So far, I have not found a clear answer to this.
I'd like to know what the equivalent is for a SQL type DATETIME and the java type, using a PreparedStatement.
I have found: http://www.java2s.com/Code/Java/Database-SQL-JDBC/StandardSQLDataTypeswithTheirJavaEquivalents.htm
But it states that SQL type "DATETIME" is the same as sql.date, but when looking at the SQL date docs (http://download.oracle.com/javase/7/docs/api/java/sql/Date.html), it says the time is truncated (all zeros).
What I want is to be able to specify a preparedStatement.setDateTime() or some sort.
The only other way I see is using a timestamp, but that would require me to change the column type, while I cannot imagine someone else never had this problem before?
Any hints?
Edit: I am using MYSQL.
The java.sql package has three date/time types:
java.sql.Date - A date only (no time part)
java.sql.Time - A time only (no date part)
java.sql.Timestamp - Both date and time
You want the last one: java.sql.Timestamp.
If you are using these types, you don't need to call a specific setter; just use:
java.util.Date date = new Date();
Object param = new java.sql.Timestamp(date.getTime());
// The JDBC driver knows what to do with a java.sql type:
preparedStatement.setObject(param);
The equivalent of MS SQL Server or MySQL DATETIME data type or Oracle DATE data type is java.sql.Timestamp.
In Java we have java.util.Date to handle both Date and Time values.
In SQL, you have commonly Dates (only dates), Time (only time) and DateTime/Timestamp (date and time).
In your Java program, usually you'll always have java.util.Date, so each time you're setting Dates/Times/DateTimes in PreparedStatements, always choose exactly which one you need, according to the database.
I had a similar problem with my Mysql having SQL date and locally in my app i only had Date
I solved like this
java.sql.Date dataStartSql = new java.sql.Date(start.getTime());
After that used the setDate normally, and I used a getTimestamp to retrive the first value.
where start is a Date object.
Related
I'm getting a SqlException on a PreparedStatement for violating a uniqueness constraint on a table (dupe key). Essentially my table looks like this:
mytable
=======
mytable_id PRIMARY KEY INT NOT NULL
fizz_id INT NOT NULL
buzz_timestamp DATETIME
The uniqueness constraint is on the buzz_timestamp; that is, no 2 records may have the same date/time "timestamp".
The PreparedStatement that inserts records into this table looks like this:
PreparedStatement ps = conn.prepareStatement(insertQuery);
ps.setDate(1, new java.sql.Date(new java.util.Date().getTime()));
So you can see I'm taking java.util.Date() ("now") and converting it to a java.sql.Date instance.
The exact error I'm seeing (the dupe key) keeps complaining that I'm trying to insert 2015-05-27 00:00:00.0000000 into the table for buzz_timestamp, but that it already exists. So, obviously, I'm using the Date API wrong, and I'm inserting dates that have nulled-out time components, and thereby producing dupe key exceptions.
So I ask: How do I correct this so that I'm truly inserting the date and time for "now"?
Use
ps.setTimestamp(new java.sql.Timestamp(System.currentTimeMillis());
See this: Using setDate in PreparedStatement
The accepted answer is correct. I'll add an explanation.
Confusing Hack
In SQL, a DATE is a date-only value lacking a time-of-day or time zone.
The mess that is the old date-time classes bundled with Java lack any such class to represent date-only values.
Instead, the Java team created a hack. They created java.sql.Date by extending java.util.Date which, despite its confusing name, has a date portion and a time-of-day portion. For the SQL-oriented subclass, they set time-of-day portion to zero values. You might think of that as "midnight". So a java.sql.Date has a time-of-day but pretends not to.
To quote the java.SQL.Date doc:
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.
For a date-and-time value in SQL use the java.sql.Timestamp class as shown in accepted answer.
java.time
These poorly designed date-time classes have been supplanted by the new java.time package built into Java 8 and later. This package was inspired by the Joda-Time library.
The Java.time package includes classes to represent date-only and time-only classes. Eventually the JDBC drivers will be upgraded to directly support the new data types. Until then, use the several conversion methods added to the old and new classes. Search StackOverflow.com for many examples and discussion, as this Question is largely a duplicate.
java.sql.Date extends java.util.Date but works differently: In SQL, DATE has no time. Therefore, the Java object also ignores hours, minutes, etc.
Try java.sql.Timestamp instead but you may need a cast (in SQL) to convert it to DATETIME.
Related:
mssql 2005 datetime and jdbc
Instead of setDate you need to try setTimestamp
java.sql.Date - A date only (no time part)
java.sql.Time - A time only (no date part)
java.sql.Timestamp - Both date and time
After an upgrade of the OJDBC client from version 11.2.0 to 12.1.0, I experience a different behavior in binding a java.sql.Date object to a PreparedStatement.
In the prepared statement, a host variable "f.plan_date = ?" should be binded with the value of a java.util.Date object, being an input obtained elsewhere in the code. The column data type in the Oracle table is "DATE" and only the date part should be taken into account - time is irrelevant.
I translated the java.util.Date object in a java.sql.Date object in the following way:
statementRegisterJobs.setDate(3, new java.sql.Date(planDate.getTime()));
This worked fine with the 11.2.0 client. However, things tend to go wrong after the upgrade towards 12.1.0. No records are retrieved anymore. After hours of debugging, I found out that the issue was related to the date variable. The following way of working gives me my records back:
statementRegisterJobs.setDate(3, java.sql.Date.valueOf("2014-08-21"));
Could someone clarify this behaviour? The java.util.Date object can eventually have a time component, and I have the undefined feeling that this could be related to the problem somehow. On the other hand, the following items should argue that a time component is neglected in a java.sql.Date, no matter how the object was constructed...
In the Java 6 API for java.sql.Date, I found the following statement: "This method is deprecated and should not be used because SQL Date values do not have a time component." (method 'getHours()'). So this would mean that the time aspect is neglected when converting the java.util.Date into a java.sql.Date.
This is confirmed by the information in the constructor documentation: "Constructs a Date object using the given milliseconds time value. If the given milliseconds value contains time information, the driver will set the time components to the time in the default time zone (the time zone of the Java virtual machine running the application) that corresponds to zero GMT."
Moreover, I'm not able to get a possible time aspect out of the java.sql.Date object: toString() gives me only the date, getHours() throws an exception.
And how can this be related to an update in a JDBC client?
Any thoughts are appreciated :) Thank you very much in advance.
Opposed to what the Java API states, when creating a java.sql.Date object by passing a milliseconds time value the time aspect seems to be stored in the object and is not defaulted to zero when using the 12.1.0 OJDBC driver.
This is the test I set up:
java.util.Date utilDate = new Date();
java.sql.Date sqlDate1 = new java.sql.Date(utilDate.getTime());
java.sql.Date sqlDate2 = java.sql.Date.valueOf("2014-08-27");
I prepared the following statement (SELECT to_char(?, 'YYYY-MM-DD HH24:MI:SS') testDate FROM dual), binded both sqlDate1 and sqlDate2 and got the following results.
With driver version 11.2.0
sqlDate1: 2014-08-27 00:00:00
sqlDate2: 2014-08-27 00:00:00
With driver version 12.1.0
sqlDate1: 2014-08-27 14:47:29
sqlDate2: 2014-08-27 00:00:00
This is not in line with the documentation in the API:
If the given milliseconds value contains time information, the driver
will set the time components to the time in the default time zone (the
time zone of the Java virtual machine running the application) that
corresponds to zero GMT.
However, knowing this I can fix the issue by forcing the time information of the sql date object to be midnight.
I have to insert data(which is also containing the timezone, i.e. 2013-01-19 00:00:00 +0530) which is in String form and the datatype of the column is DATETIMEOFFSET. I have tried both java.util.date and sql.date but could not find any solution.
If you're using the Microsoft JDBC driver, you can use the DateTimeOffset class, constructing instances with the valueOf method.
You'll need to parse the value out into local time and offset (in order to pass the two parts separately) but that shouldn't be too bad using SimpleDateFormat. (The Z format specifier in SimpleDateTimeFormat will handle offsets like +0530.) Alternatively, use Joda Time which will make life easier still, as it will allow you to parse to a DateTime which lets you get the offset as well as the local time in one go. I would personally use Joda Time and create a method to convert from a DateTime to a DateTimeOffset.
I have a database which is going to have UMT timestamps in standard sql format. How can I pull that data and set a java date object with it?
As far as I know mysql is yyyy-mm-dd hh:mm:ss As for java, the date / time stuff has always eluded me.
If anyone knows of a good library for this I am open to suggestions.
Why don't directly read it as Date
Date date = resultSet.getTimestamp("date_field");
Timestamp timestamp = resultSet.getTimestamp("date_time_field");
See
ResultSet.getTimeStamp()
A Timestamp is a subclass of a Date, which means it is usable everywhere where a Date is. The only difference is, Timestamp is more precise (due to the SQL specification) than Date is.
Just use:
Timestamp t = resultSet.getTimestamp("columnname");
Date d = t;
That having said, there are some benefits of converting the JDBC returned timestamp into a proper Date value, omitting nanoseconds. When you compare a Timestamp and a Date in some remote part of your app, the Timestamp and the Date won't be equal, even though they seem to be "rougly" the same time value. So if this could cause problem, create a new Date instance using only the .getTime() value returned by Timestamp)
More on this in my blog: Timestamp and Date equality when using Hibernate
(even though the blog entry is about Hibernate, it applies to your case as well)
I am trying to read several dates from my database but under certain circumstances I get a ' java.sql.SQLException Bad format for DATE'. Here is my code :
Date entryDateD = res.getDate("entryDate");
In debug mode I see that the content of entryDateD '1996-9-15' as is in my database..
Although I would have to mention that I read other dates too from my database which I notice are of the format 'xxxx-0y-zz'. What I want to say is that in case of a month being less than 10 there is a zero added in front of it which in this case is not added. I suspect that this might have something to do with it.
(this zero does not appear in the database itself though not only in this date but in any date)
thanx in advance :)
Just a guess, but what MySQL column type do you have for entryDate??
By default a date type in MySQL will generate an yyyy-mm--dd format; the missing zero leads me to believe that the column type may be varchar or other non-date type at DB level.
This could be the cause of your problems at Java level...
If you represent it as java.util.Date, you have the advantage of allowing the JDBC driver to worry about handling any format issues with the database.
As for how it's rendered in your display, that's up to you and your use of the java.text.DateFormat class.
You're doing the right thing by representing a date as java.util.Date in your app, but you need to understand that formatting is a separate issue from the type.
Java has a child class of java.util.Date, called java.sql.Date
The easiest way to create a Java SQL Date is by calling the constructor with a Utility Date.
java.util.Date uDate = res.getDate("entryDate");
java.sql.Date sDate = new java.sql.Date(uDate.getTime());
If you want to get res.getDate("entryDate") as YYYY-MM-DD then you need to cast as date in your query like this:
SELECT
...
CAST(entryDate as DATE)as entryDate,
...
FROM your_table;
If you feel this is helpful then do upVote to make it useful for others.