Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert java.util.Date to datastax's LocalDate

I'm trying to convert a date in yyyy-MM-dd String format to datastax's LocalDate. I'm using following code to do that.

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

public static LocalDate getDate(String date) throws ParseException {
    Date d = DATE_FORMAT.parse(date);
    return LocalDate.fromMillisSinceEpoch(d.getTime());
}

When I tested this method I'm not getting expected results.

public static void main(String[] args) throws ParseException {
    System.out.println(getDate("2017-11-22"));
}
// Actual Output:
2017-11-21
// Excpected Output:
2017-11-22

Is there anything I'm missing here?

like image 428
pkgajulapalli Avatar asked Dec 31 '25 09:12

pkgajulapalli


2 Answers

TL;DR

public static LocalDate getDate(String date) {
    java.time.LocalDate jtld = java.time.LocalDate.parse(date);
    return LocalDate.fromYearMonthDay(jtld.getYear(), jtld.getMonthValue(), jtld.getDayOfMonth());
}

java.time

The Java date and time classes you are using, Date and SimpleDateFormat, are long outdated and poorly designed, and the latter in particular has proven troublesome. Furthermore, java.time, the modern Java date and time API, provides a class also called LocalDate that matches your need much better than the outdated Date class. java.time.LocalDate is a date without time of day. So using it completely eliminates the time zone issue that caused your problem. Your string, 2017-11-22, is in ISO 8601 format, which LocalDate parses as its default, that is, without any explicit formatter, which also makes your task easier.

What went wrong in your code?

Your SimpleDateFormat instance defaults to using the time zone setting of your JVM (probably Asia/Kolkata time) and therefore parses your date string into the equivalent of Wed Nov 22 2017 00:00:00 GMT+0530 (IST), which in turn is the same point in time as November 21, 2017, at 18:30 UTC. The documentation of LocalDate.fromMillisSinceEpoch() says: “if the given number does not correspond to a whole number of days, it will be rounded towards 0.” In other words, it rounds to 2017-11-21.

If you really insist on sticking with the oldfashioned SimpleDateFormat, I wish you good luck (sorry, you may need it). If so, assign it a time zone of UTC, and it will parse into a date in UTC, and your existing method will work no matter the time zone setting of the JVM.

private static final SimpleDateFormat DATE_FORMAT = buildOldfashionedDateFormatInstance();

private static SimpleDateFormat buildOldfashionedDateFormatInstance() {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
    return dateFormat;
}

Links

  • Oracle Tutorial: Date Time
  • com.datastax.driver.core.LocalDate.fromMillisSinceEpoch() documentation
like image 134
Ole V.V. Avatar answered Jan 02 '26 22:01

Ole V.V.


Something like:

public static LocalDate convertDate(final String date) {
    String[] arr = date.split("-");
    if (arr.length != 3)
        return null;
    return LocalDate.fromYearMonthDay(Integer.parseInt(arr[0]),
            Integer.parseInt(arr[1]),
            Integer.parseInt(arr[2]));
}
like image 21
Alex Ott Avatar answered Jan 02 '26 23:01

Alex Ott



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!