I want to create a java.sql.Date object of the format "YYYY". It should have only the year. I researched a lot but couldn't find a way to do it.
-
3Possible duplicate of [Java string to date conversion](https://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – fantaghirocco Nov 19 '18 at 10:08
-
1You cannot. While a `java.sql.Date` pretends only to have a date it, it at least has a date, not only a year. Behind the scenes it has a point in time with millisecond presicion. That said, the class has design issues and is long outdated. Do you absolutely need one nevertheless? I’d recommend `Year` and/or `LocalDate` from java.time, the modern Java date and time API, instead. They do live up to their names and only hold what the names say. Neither of the mentioned classes can have a format in them (but `Year.toString` produces the format you seem to want). – Ole V.V. Nov 19 '18 at 19:40
2 Answers
tl;dr
Never use terrible java.sql.Date
class, badly designed with multiple flaws.
Use either java.time.Year
object, or an integer.
myPreparedStatement.setObject( … , Year.of( 2018 ) ) ;
…or, while using Year
in other parts of your code:
myPreparedStatement.setInt( … , Year.of( 2018 ).getValue() ) ;
java.time
The modern solution uses the java.time classes that years ago supplanted the terrible old date-time classes of SimpleDateFormat
, java.util.Date
, java.sql.Date
, and so on.
The Year
class neatly represents a year value. Using this class in your code gives you type-safety and makes your code more self-documenting.
Parsing a string input.
Year y = Year.parse( "2018" ) ;
Parsing an integer input.
Year y = Year.of( 2018 ) ; // Integer literal.
JDBC
As of JDBC 4.2 we can directly exchange java.time types.
Exchange Year
object
I do not know if this includes the Year
class and YEAR
data type in MySQL. But give it a shot. If not, make a feature request to your JDBC driver vendor to extend support. Seems like a justifiable expectation given the fact that MySQL has an explicit YEAR
type.
myPreparedStatement.setObject( … , y ) ;
Retrieval.
Year y = myResultSet.getObject( … , Year.class ) ;
Exchange integer
If your JDBC driver cannot use java.time.Year
directly, use integer.
myPreparedStatement.setInt( … , y.getValue() ) ; // Pass year as an integer number.
Retrieval.
Year y = Year.of( myResultSet.getInt( … ) ) ; // Retrieve integer, convert to `Year` object.
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, 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.

- 303,325
- 100
- 852
- 1,154
-
Note that JDBC 4.2 only defines support for `LocalDate`, `LocalTime`, `LocalDateTime`, `OffsetTime` and `OffsetDateTime`, all other java.time types are driver-specific extensions. – Mark Rotteveel Nov 20 '18 at 12:34
You need to create a java.util.Date
and then convert this to a java.sql.Date
using the constructor that takes in a long
.
Example:
String year = "2018";
DateFormat format = new SimpleDateFormat("yyyy");
java.util.Date utilDate = format.parse(year);
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
However, it's not "only a year". Dates in Java always have a time component, so this isn't possible - it will be "1 Jan 2018 00:00:00 GMT" in my example. Is this close enough to what you want, or could you refine your question?
In addition, a java.sql.Date
extends java.util.Date
, so ideally you'd use the former wherever possible to satisfy the Liskov substitution principle.

- 922
- 12
- 39
-
Actually, I am trying to insert data into a column of type "YEAR" in a table in MySQL database using JBOSS Teiid. And in order to do this Teiid requires the data in sql date format. – Hazzard Nov 19 '18 at 10:51
-
FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Nov 19 '18 at 21:26
-
1The class JavaDoc tells you to ignore the inheritance relationship between `java.util.Date` and `java.sql.Date` that resulting from a terrible hack in bad design. – Basil Bourque Nov 19 '18 at 21:33