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?
public static LocalDate getDate(String date) {
java.time.LocalDate jtld = java.time.LocalDate.parse(date);
return LocalDate.fromYearMonthDay(jtld.getYear(), jtld.getMonthValue(), jtld.getDayOfMonth());
}
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.
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;
}
com.datastax.driver.core.LocalDate.fromMillisSinceEpoch() documentationSomething 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]));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With