3

The following code prints out "3920-06-02", but it's supposed to be "2020-05-02". What did I do wrong?

import java.sql.Date
// ...

public static void main(String[] args) {
    Date May0220 = new Date(2020,  5,  2);
    System.out.println(May0220.toString());
}

I want to use java.sql and not java.util.

Chris Rahmé
  • 357
  • 2
  • 6
  • 20
  • 6
    Don't use that constructor. It's been deprecated for 15 years now. – The Impaler Mar 14 '20 at 16:30
  • @TheImpaler So what do I do instead? – Chris Rahmé Mar 14 '20 at 16:30
  • 1
    You probably want a local date without time. If so use java.time.LocalDate. Is there any specific reason you want to use java.sql.Date? – The Impaler Mar 14 '20 at 16:31
  • 6
    use LocalDate like this `LocalDate May0220 = LocalDate.of(2020, 5, 2);` – falknis Mar 14 '20 at 16:33
  • @TheImpaler I want java.sql.Date because I want that specific format since it works with the SQL Date type. I'm changing every Date into LocalDate to see if it works. – Chris Rahmé Mar 14 '20 at 16:50
  • 3
    You can also create java.sql.Date from LocalDate: `Date sqlDate = Date.valueOf(May0220)` – falknis Mar 14 '20 at 16:54
  • https://stackoverflow.com/q/29168494 – Dawood ibn Kareem Mar 14 '20 at 16:56
  • TheImpaler, falknis - Thanks, it works! – Chris Rahmé Mar 14 '20 at 17:21
  • *"What did I do wrong?"* You didn't **read the documentation**, i.e. the javadoc of the [`Date` constructor](https://docs.oracle.com/javase/8/docs/api/java/sql/Date.html#Date-int-int-int-). – Andreas Mar 14 '20 at 17:53
  • 1
    `LocalDate` works very nicely with SQL date. [Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2](https://stackoverflow.com/questions/43039614/insert-fetch-java-time-localdate-objects-to-from-an-sql-database-such-as-h2). You don’t want `java.sql.Date`. It’s poorly designed (you haven’t seen but a slight bit of its problems) and long outdated. – Ole V.V. Mar 15 '20 at 11:50
  • Closely related: [java.util.Date and getYear()](https://stackoverflow.com/questions/9243578/java-util-date-and-getyear) – Ole V.V. Mar 16 '20 at 09:02
  • 1
    If it's been deprecated since 15 years now, maybe it's time to just remove this technical debt already....? – BdR Feb 20 '22 at 16:19

2 Answers2

2

It seems as if java.sql.Date; uses the year from 1900, and uses array like indexing for the month, so it's off one less than what it should be.

This is what I did to get your desired result.

public static void main(String[] args) 
{
    Date May0220 = new Date(2020 - 1900, 5 - 1, 2);
    System.out.println(May0220+"");
}

A more general form would be

{
    int year = 2020;
    int month = 5;
    Date date = new Date(year - 1900, month - 1, 2);
    System.out.println(date+"");
}

Good Luck!

rohan1122
  • 120
  • 4
  • Yeah, I was thinking of doing that but I thought there must be a more elegant way of doing it. Thanks! – Chris Rahmé Mar 14 '20 at 17:14
  • @ChrisRahmé Most JDBC drivers now support java.time.LocalDate using `setObject()` and `getObject()`. java.time.LocalDate is always local, while java.sql.Date is world time; they represent two different things. If your app runs in a different time zone than your database you'll see wrong conversions. – The Impaler Mar 14 '20 at 20:01
1

You can use this reference How to Get Current Date and Time in Java to get the output like you expected . I've Just modified the code in the example by removing the time part.

The librararies are java.time.format.DateTimeFormatter; and java.time.LocalDateTime.

import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;  
public class PrintDateTime {  
  public static void main(String[] args) {  
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDateTime now = LocalDateTime.now();
    System.out.println(dtf.format(now));
 }  
}  

Hope you find it useful !

Kaviranga
  • 576
  • 2
  • 10
  • 24
  • 1
    Thanks for showing the modern solution! Still simpler would be `System.out.println(LocalDate.now(ZoneId.systemDefault()));`. – Ole V.V. May 04 '21 at 12:35