In order to make our code more standard, we were asked to change all the places where we hardcoded our SQL variables to prepared statements and bind the variables instead.
I am however facing a problem with the setDate().
Here is the code:
DateFormat dateFormatYMD = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
DateFormat dateFormatMDY = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date now = new Date();
String vDateYMD = dateFormatYMD.format(now);
String vDateMDY = dateFormatMDY.format(now);
String vDateMDYSQL = vDateMDY ;
java.sql.Date date = new java.sql.Date(0000-00-00);
requestSQL = "INSERT INTO CREDIT_REQ_TITLE_ORDER (REQUEST_ID," +
" ORDER_DT, FOLLOWUP_DT) " + "values(?,?,?,)";
prs = conn.prepareStatement(requestSQL);
prs.setInt(1,new Integer(requestID));
prs.setDate(2,date.valueOf(vDateMDYSQL));
prs.setDate(3,date.valueOf(sqlFollowupDT));
I get this error when the SQL gets executed:
java.lang.IllegalArgumentException
at java.sql.Date.valueOf(Date.java:138)
at com.cmsi.eValuate.TAF.TAFModuleMain.CallTAF(TAFModuleMain.java:1211)
Should I use setString() instead with a to_date()?
❐ Using java.sql.Date
If your table has a column of type DATE:
java.lang.String
The method java.sql.Date.valueOf(java.lang.String) received a string representing a date in the format yyyy-[m]m-[d]d. e.g.:
ps.setDate(2, java.sql.Date.valueOf("2013-09-04"));
java.util.Date
Suppose you have a variable endDate of type java.util.Date, you make the conversion thus:
ps.setDate(2, new java.sql.Date(endDate.getTime());
Current
If you want to insert the current date:
ps.setDate(2, new java.sql.Date(System.currentTimeMillis()));
// Since Java 8
ps.setDate(2, java.sql.Date.valueOf(java.time.LocalDate.now()));
❐ Using java.sql.Timestamp
If your table has a column of type TIMESTAMP or DATETIME:
java.lang.String
The method java.sql.Timestamp.valueOf(java.lang.String) received a string representing a date in the format yyyy-[m]m-[d]d hh:mm:ss[.f...]. e.g.:
ps.setTimestamp(2, java.sql.Timestamp.valueOf("2013-09-04 13:30:00");
java.util.Date
Suppose you have a variable endDate of type java.util.Date, you make the conversion thus:
ps.setTimestamp(2, new java.sql.Timestamp(endDate.getTime()));
Current
If you require the current timestamp:
ps.setTimestamp(2, new java.sql.Timestamp(System.currentTimeMillis()));
// Since Java 8
ps.setTimestamp(2, java.sql.Timestamp.from(java.time.Instant.now()));
ps.setTimestamp(2, java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()));
tl;dr
With JDBC 4.2 or later and java 8 or later:
myPreparedStatement.setObject( … , myLocalDate )
…and…
myResultSet.getObject( … , LocalDate.class )
Details
The Answer by Vargas is good about mentioning java.time types but refers only to converting to java.sql.Date. No need to convert if your driver is updated.
java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat. The Joda-Time team also advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
LocalDate
In java.time, the java.time.LocalDate class represents a date-only value without time-of-day and without time zone.
If using a JDBC driver compliant with JDBC 4.2 or later spec, no need to use the old java.sql.Date class. You can pass/fetch LocalDate objects directly to/from your database via PreparedStatement::setObject and ResultSet::getObject.
LocalDate localDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );
myPreparedStatement.setObject( 1 , localDate );
…and…
LocalDate localDate = myResultSet.getObject( 1 , LocalDate.class );
Before JDBC 4.2, convert
If your driver cannot handle the java.time types directly, fall back to converting to java.sql types. But minimize their use, with your business logic using only java.time types.
New methods have been added to the old classes for conversion to/from java.time types. For java.sql.Date see the valueOf and toLocalDate methods.
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
…and…
LocalDate localDate = sqlDate.toLocalDate();
Placeholder value
Be wary of using 0000-00-00 as a placeholder value as shown in your Question’s code. Not all databases and other software can handle going back that far in time. I suggest using something like the commonly-used Unix/Posix epoch reference date of 1970, 1970-01-01.
LocalDate EPOCH_DATE = LocalDate.ofEpochDay( 0 ); // 1970-01-01 is day 0 in Epoch counting.
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.
The docs explicitly says that java.sql.Date will throw:
IllegalArgumentException - if the date given is not in the JDBC date escape format (yyyy-[m]m-[d]d)
Also you shouldn't need to convert a date to a String then to a sql.date, this seems superfluous (and bug-prone!). Instead you could:
java.sql.Date sqlDate := new java.sql.Date(now.getTime());
prs.setDate(2, sqlDate);
prs.setDate(3, sqlDate);
The problem you're having is that you're passing incompatible formats from a formatted java.util.Date to construct an instance of java.sql.Date, which don't behave in the same way when using valueOf() since they use different formats.
I also can see that you're aiming to persist hours and minutes, and I think that you'd better change the data type to java.sql.Timestamp, which supports hours and minutes, along with changing your database field to DATETIME or similar (depending on your database vendor).
Anyways, if you want to change from java.util.Date to java.sql.Date, I suggest to use
java.util.Date date = Calendar.getInstance().getTime();
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
// ... more code here
prs.setDate(sqlDate);
If you want to add the current date into the database, I would avoid calculating the date in Java to begin with. Determining "now" on the Java (client) side leads to possible inconsistencies in the database if the client side is mis-configured, has the wrong time, wrong timezone, etc. Instead, the date can be set on the server side in a manner such as the following:
requestSQL = "INSERT INTO CREDIT_REQ_TITLE_ORDER (" +
"REQUEST_ID, ORDER_DT, FOLLOWUP_DT) " +
"VALUES(?, SYSDATE, SYSDATE + 30)";
...
prs.setInt(1, new Integer(requestID));
This way, only one bind parameter is required and the dates are calculated on the server side will be consistent. Even better would be to add an insert trigger to CREDIT_REQ_TITLE_ORDER and have the trigger insert the dates. That can help enforce consistency between different client apps (for example, someone trying to do a fix via sqlplus.
Not sure, but what I think you're looking for is to create a java.util.Date from a String, then convert that java.util.Date to a java.sql.Date.
try this:
private static java.sql.Date getCurrentDate(String date) {
java.util.Date today;
java.sql.Date rv = null;
try {
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
today = format.parse(date);
rv = new java.sql.Date(today.getTime());
System.out.println(rv.getTime());
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
return rv;
}
}
Will return a java.sql.Date object for setDate();
The function above will print out a long value:
1375934400000
Related
I have a column in my table of Date type in MYSQL and inserting the date format of 25-March-2019 hh:mm:ss returns an error telling me incorrect data value.
So I have my code written like this:
String startdt=request.getParameter("startdate");
String enddate=request.getParameter("enddate");
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
Date Startdate=dateFormat.parse(startdt);
Date Enddate=dateFormat.parse(enddate);
And I am passing Startdate and Enddate to a function that inserts into my table column.
Is there a way I can have Startdate and Enddate above just return in yyyy-mm-dd without the time so I can insert to my db without error?
tl;dr
myPreparedStatement
.setObject(
LocalDate.parse( "2019-01-23" )
) ;
DATE in MySQL is date-only
The DATE type in MySQL is a date-only value, without time-of-day and without time zone.
Excerpting from MySQL 8.0 documentation:
The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.
Use a date-only type in Java for data coming from a date-only type in your database. The java.util.Date class you are trying to use is not a date, it is a moment in UTC, a date with time-of-day and offset-from-UTC of zero, all tracked as a count of milliseconds from the first moment of 1970 in UTC. The misnaming of that class is only the first of many poor design choices made by those programmers. Move on to java.time classes instead. Stop using Date.
MM = month number, not name
Your format of "yyyy-MM-dd" is for a numeric month, not the string of month name shown in your example value of 25-March-2019.
Avoid legacy date-time classes
The SimpleDateFormat and Date classes are terrible, a wretched mess of bad design. They were supplanted years ago with the adoption of JSR 310, implemented in the java.time classes.
Smart objects, not dumb strings
Exchange objects with your database where possible, not text.
As of JDBC 4.2, we can directly exchanged java.time objects with the database. For a date-only value, as with SQL-standard DATE type, use the java.time.LocalDate class.
Apparently, your text inputs for date values is YYYY-MM-DD which is standard ISO 8601 format. The java.time classes use ISO 8601 formats by default. So no need to specify a formatting pattern.
LocalDate localDate = LocalDate.parse( "2019-01-23" ) ;
myPreparedStatement.setObject( … , localDate ) ;
Retrieval.
LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;
localDate.toString(): 2019-01-23
If you want to produce a string representing the value of that LocalDate object in a different textual format, use the DateTimeFormatter class. Search Stack Overflow for more info as it, like the rest of your Question, has been covered many times already on Stack Overflow. Do search Stack Overflow before posting.
Tip: Generally best to use a PreparedStatement in your JDBC work. One major benefit is thwarting SQL Injection security attacks.
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.
Java 7 and ThreeTen Backport
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("d-MMMM-uuuu HH:mm:ss", Locale.ENGLISH);
String dateFromHtmlForm = "25-March-2019 22:43:55";
LocalDateTime dateTime = LocalDateTime.parse(dateFromHtmlForm, formatter);
// We are discarding the time of day and only saving the date
java.sql.Date dateToSave = DateTimeUtils.toSqlDate(dateTime.toLocalDate());
String insertSql = "insert into your_table (your_date_column) values (?);";
try (PreparedStatement insertStatement
= yourDatabaseConnection.prepareStatement(insertSql)) {
insertStatement.setDate(1, dateToSave);
int rowsInserted = insertStatement.executeUpdate();
}
As has already been said, pass date objects to MySQL, not strings. In Java 8 and later these would have been LocalDate objects, but in Java 7 we will need to make do with the poorly designed java.sql.Date class. It’s still better than strings. And the conversion from LocalDate is straightforward.
On Java 7 we can use java.time through the backport, ThreeTen Backport (ThreeTen for JSR-310). My imports are:
import org.threeten.bp.DateTimeUtils;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.format.DateTimeFormatter;
Why would we want to use an external library for this? There are pros and cons, of course. Advantages include:
java.time is so much nicer to work with than the old-fashoined Date and SimpleDateFormat and gives clearer code.
It’s future-proof: once you move to Java 8 or later, all you need to do is change your import statements (and discard the library and retest).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7.
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
My requirement is to return the dueDate field as a date to the calling service.
The back end code returns the date in mm/dd/yy. When I map those fields to the Java code, my object contains the date field of type java.sql.Date.
The field that is defined in the object is (note it's the pseudo):
import java.sql.Date;
private Date dueDate;
/**
* #return the dueDate
*/
public Date getDueDate() {
return dueDate;
}
/**
* #param DueDate the DueDate to set
*/
public void setDueDate(Date dueDate) {
this.dueDate = dueDate;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("DueDetails [dueAmount=").append(dueAmount).append(", dueDate=").append(dueDate)
.append("]");
return builder.toString();
}
When I print the object, the Date field comes in this form:
dueDate=Thu Oct 25 20:00:00 EDT 2018
dueDate=Thu Aug 02 20:00:00 EDT 2018
When I query from backend, it shows me the proper format (mm/dd/yy), which I should return to the calling service.
check this
//converting java.util.Date to java.sql.Date in Java
java.sql.Date sqlDate = new java.sql.Date(now.getTime());
System.out.println("Converted value of java.sql.Date : " + sqlDate);
//converting java.sql.Date to java.util.Date back
java.util.Date utilDate = new java.util.Date(sqlDate.getTime());
System.out.println("Converted value of java.util.Date : " + utilDate);
from this link: http://www.java67.com/2012/12/how-to-convert-sql-date-to-util-date.html
Then you can use SimpleDateFormat to format the date as you like:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String strdate = simpleDateFormat.format(myJavaDate);
System.out.println(strdate);
java.util.Date vs java.sql.Date
Your output looks to be coming from a java.util.Date rather than a java.sql.Date.
It is unfortunately easy to mixup the two. Besides the Date name, the sql one technically is a subclass of the other util one. Beware: This is a hack, and a bad hack at that. The documentation warns us to pretend the two are not in an inheritance relationship. But the compiler does not know that.
Here is some example code showing these two classes and the different behavior of their respective toString method.
// Legacy classes
System.out.println( "java.sql.Date: " + new java.sql.Date( Instant.now().toEpochMilli() ) ) ;
System.out.println( "java.util.Date: " + new java.util.Date() ) ;
See this code run live at IdeOne.com.
java.sql.Date: 2018-07-31
java.util.Date: Tue Jul 31 22:44:14 GMT 2018
You can see the java.sql.Date::toString method uses the shorter YYYY-MM-DD format used in SQL environments. That format also happens to comply with ISO 8601 standard as well, by the way.
In contrast, the output you report matches that of java.util.Date::toString.
java.time
The issue is moot. You are using terrible old date-time classes that were supplanted years ago by the java.time classes.
java.sql.Date is replaced by java.time.LocalDate, a date-only only value without a time-of-day and without a time zone. (FYI, java.sql.Date pretends to have no time-of-day or time zone but actually has both, as an awkward subclass of java.util.Date.)
java.util.Date is replaced by java.time.Instant. Both represent a moment in UTC, though Instant has a finer resolution of nanoseconds instead of milliseconds. (FYI, java.util.Date actually has a time zone buried deep, inaccessible without getter/setter methods, but used in equals etc. One of many poor design decisions in these legacy classes.)
Here is some code, counterparts to that seen above.
// Modern classes
System.out.println( "LocalDate.now(): " + LocalDate.now() ;
System.out.println( "Instant.now(): " + Instant.now() ) ;
System.out.println( "ZonedDateTime.now( … ): " + ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) ) ) ;
See this code run live at IdeOne.com.
LocalDate.now(): 2018-07-31
Instant.now(): 2018-07-31T22:57:27.763Z
ZonedDateTime.now( … ): 2018-07-31T23:57:27.904+01:00[Africa/Tunis]
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.
I'm using SimpleDateFormat to parse string to Date.
After the parse, I'm loading this date to mysql. The problem is that milliseconds is not being parsed to Date and when I insert the object on Mysql its getting rounded.
myStringDate = "2018-02-02 23:59:59.700"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.SSS");
myObject.setDate(fmt.parse(myStringDate );
When I debug the code I can see the Date as Sun Feb 02 23:59:59 BRST 2018 (its not storing milliseconds)
The data is stored on mysql as '2017-02-03 00:00:00'
My model is mapped as :
import javax.persistence.*;
import java.util.Date;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "date")
private Date date;
And column on MySqls is TYPE DATETIME.
I think the milliseconds are actually being parsed, you just aren't seeing them with the default formatting that you're getting when you're displaying the date for debugging purposes.
Using this code:
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String myStringDate = "2018-02-02 23:59:59.700";
Date date = fmt.parse(myStringDate);
System.out.println(date);
System.out.println(fmt.format(date));
I get this output:
Fri Feb 02 23:59:59 EST 2018
2018-02-02 23:59:59.700
Update: Make sure you use capital MM for the month, not mm.
tl;dr
myPreparedStatement.setObject(
… ,
LocalDateTime.parse(
"2017-02-03 00:00:00".replace( " " , "T" )
)
)
Smart types, not dumb strings
The data is stored on mysql as '2017-02-03 00:00:00'
No, the data is not stored that way. You said:
column on MySqls is TYPE DATETIME.
That means the date-time is not stored as text, and does not have a “format”.
As the documentation says:
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format.
Key words there are: retrieves and displays. After extracting the date-time value, some text is constructed to represent that value. Do not conflate the textual representation of the date-time value with the date-time value. Both your database and Java have their own internally-defined way of storing a date-time, but neither use plain text. Both your database and Java can generate text to display a date-time value, as needed.
Unzoned
I am a Postgres user, not MySQL, but it seems that its DATETIME type is akin to the SQL-standard TIMESTAMP WITHOUT TIME ZONE type. This means it does not represent an actual moment, is not a point on the timeline. It represents potential moments along a range of about 26-27 hours. Without the context of a time zone or offset-from-UTC, it has no real meaning.
java.time classes
Avoid the legacy date-time types. Use only java.time classes instead. According to this Question, JPA & Hibernate now support the java.time types.
If you do have input text such as 2018-02-02 23:59:59.700, parse as a LocalDateTime, given the lack of zone/offset information. Like the MySQL type DATETIME and the SQL type TIMESTAMP WITHOUT TIME ZONE, this class lacks any concept of zone/offset. To parse, convert from SQL-style with a SPACE in the middle to ISO 8601 standard format with a T in the middle.
String input = "2018-02-02 23:59:59.700".replace( " " , "T" ) ;
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to define a formatting pattern.
LocalDateDate ldt = LocalDateTime.parse( input ) ;
No need for strings when communicating with your database. As of JDBC 4.2 and later, you can directly exchange java.time objects. (Or let JPA/Hibernate do so under-the-covers.)
myPreparedStatement.setObject( … , ldt ) ;
And retrieval.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
FYI, if you are actually trying to track specific moments in time, you are using the wrong types. You should be using TIMESTAMP in MySQL or TIMESTAMP WITH TIME ZONE in standard SQL, and in Java use Instant and ZonedDateTime.
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, 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.
If you are using MySQL's version 5.6.4, you can see this happen by declaring columns with fractional-second time datatypes.
This documentation shows more in detail about this feature, and as far as a quick check is concerned - you may try SELECT NOW(3) should give you the present time from your MySQL server's operating system with millisecond precision and instead if you are getting an error then you are not using the right version.
Alongside to that, moving from the older Connector/J driver to mysql-connector-java-5.1.26.jar is very much suggested.
Hope this helps answer your question!
The pattern for month of the year should be MM (uppercase) not mm (lowercase) for SimpleDateFormat. It is possible your code is reading the month as a minutes value.
The date format in SQL is YY-MM-dd hh24:mi:ss:mmm while in Java is YY-MM-dd HH:mm:ss.SSS
I used LocalDateTime:
#Column(name = "date", columnDefinition = "DATETIME(3)")
private LocalDateTime date;
I have following web application:
Users can enter java simple date format patterns and a date (of course matching to the java simple date format pattern) and I want to store these date in an oracle database.
Therefore I need to translate the java simple date format pattern into the oracle pattern.
E.g:
"dd-MM-yyyy HH:mm:ss" into "DD-MM-YYYY HH24:MI:SS"
"dd-MM-yy HH:mm:ss" into "DD-MM-YY HH24:MI:SS"
"dd-MM-yy HH:mm" into "DD-MM-YY HH24:MI"
and so on.
Instead of the following code just having one SimpleDateFormat I would like to have all or at least a big bunch of SimpleDateFormatPatterns translated into Oracle pattern:
SimpleDateFormat sFormat = new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss");
String sqlSnippet = "TO_DATE('" + sFormat.format(date) + "','DD-MM-YYYY HH24:MI:SS')";
Is there a library or maybe just a mapping list to do this?
Thanks.
Edit:
I need to build the SQL by hand as the user defines the criteria, compare operators and joins in the user interface.
In the end I have something like this
AND col2 > TO_DATE('26-09-2012','DD-MM-YYYY')
Therefore I need to translate the java simple date format pattern into the oracle pattern
No, you don't. You should instead use a PreparedStatement, and call setDate or setTimestamp on it to specify the value you're interested in.
Avoid string conversions unless they're fundamentally part of what you're trying to do (e.g. displaying a date/time in a UI). For simply transferring information from your app to your database or vice versa, you should reduce the number of conversions required as far as possible.
The Answer by Jon Skeet is correct but is now outdated in referring to some legacy classes. The java.sql.Date and java.sql.Timestamp and related classes are now supplanted by the java.time classes, LocalDate and Instant respectively. But your Question demands the LocalDateTime class.
Smart objects, not dumb strings
You objects to represent your date-time values. As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
Your inputs lack any indicator of time zone or offset-from-UTC. So parse in Java as a LocalDateTime for storage in a column of a type similar to SQL-standard TIMESTAMP WITHOUT TIME ZONE.
DateTimeFormatter f1 = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH:mm:ss" ) ;
DateTimeFormatter f2 = DateTimeFormatter.ofPattern( "dd-MM-uu HH:mm:ss" ) ;
DateTimeFormatter f3 = DateTimeFormatter.ofPattern( "dd-MM-uu HH:mm" ) ;
Choose a formatter by length of the input string.
LocalDateTime ldt = LocalDateTime.parse( myInputString , f2 ) ;
I need to build the SQL by hand as the user defines the criteria, compare operators and joins in the user interface. In the end I have something like this
String sqlSnippet = "TO_DATE('" + sFormat.format(date) + "','DD-MM-YYYY HH24:MI:SS')";
No, do not embed your date-time value as text in a String of SQL. Instead, use a PreparedStatement with ? placeholders replaced with your LocalDateTime object.
String sql = "SELECT when FROM tbl WHERE when > ? ;" ;
Pass the object to be slipped into that placeholder at runtime.
myPreparedStatement.setObject( … , ldt ) ;
Retrieval:
LocalDateTime ldt = myResultSet.getObject( … ; LocalDateTime.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, 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.
I need to add the current date into a prepared statement of a JDBC call. I need to add the date in a format like yyyy/MM/dd.
I've try with
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
pstm.setDate(6, (java.sql.Date) date);
but I have this error:
threw exception
java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
Is there a way to obtain a java.sql.Date object with the same format?
A java.util.Date is not a java.sql.Date. It's the other way around. A java.sql.Date is a java.util.Date.
You'll need to convert it to a java.sql.Date by using the constructor that takes a long that a java.util.Date can supply.
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
These are all too long.
Just use:
new Date(System.currentTimeMillis())
Simply in one line:
java.sql.Date date = new java.sql.Date(Calendar.getInstance().getTime().getTime());
new java.sql.Date(Calendar.getInstance().getTimeInMillis());
In order to get "the current date" (as in today's date), you can use LocalDate.now() and pass that into the java.sql.Date method valueOf(LocalDate).
import java.sql.Date;
...
Date date = Date.valueOf(LocalDate.now());
Since the java.sql.Date has a constructor that takes 'long time' and java.util.Date has a method that returns 'long time', I just pass the returned 'long time' to the java.sql.Date to create the date.
java.util.Date date = new java.util.Date();
java.sql.Date sqlDate = new Date(date.getTime());
tl;dr
myPreparedStatement.setObject( // Directly exchange java.time objects with database without the troublesome old java.sql.* classes.
… ,
LocalDate.parse( // Parse string as a `LocalDate` date-only value.
"2018-01-23" // Input string that complies with standard ISO 8601 formatting.
)
)
java.time
The modern approach uses the java.time classes that supplant the troublesome old legacy classes such as java.util.Date and java.sql.Date.
For a date-only value, use LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.
The java.time classes use standard formats when parsing/generating strings. So no need to specify a formatting pattern.
LocalDate ld = LocalDate.parse( input ) ;
You can directly exchange java.time objects with your database using a JDBC driver compliant with JDBC 4.2 or later. You can forget about transforming in and out of java.sql.* classes.
myPreparedStatement.setObject( … , ld ) ;
Retrieval:
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.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, 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, 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.
Will do:
new Date(Instant.now().toEpochMilli())
You can achieve you goal with below ways :-
long millis=System.currentTimeMillis();
java.sql.Date date=new java.sql.Date(millis);
or
// create a java calendar instance
Calendar calendar = Calendar.getInstance();
// get a java date (java.util.Date) from the Calendar instance.
// this java date will represent the current date, or "now".
java.util.Date currentDate = calendar.getTime();
// now, create a java.sql.Date from the java.util.Date
java.sql.Date date = new java.sql.Date(currentDate.getTime());
all you have to do is this
Calendar currenttime = Calendar.getInstance(); //creates the Calendar object of the current time
Date sqldate = new Date((currenttime.getTime()).getTime()); //creates the sql Date of the above created object
pstm.setDate(6, (java.sql.Date) date); //assign it to the prepared statement (pstm in this case)