-4

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.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Hazzard
  • 11
  • 8
  • 3
    Possible duplicate of [Java string to date conversion](https://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – fantaghirocco Nov 19 '18 at 10:08
  • 1
    You 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 Answers2

2

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?

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.

Basil Bourque
  • 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
1

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.

Jakg
  • 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
  • 1
    The 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