Skip to content
Advertisement

Java Instant.parse cannot validate date

I have an instant field and trying to validate the values in this field using the following approach:

Instant.parse("2021-09-29 09:35:07.531")

However, it throws the error:

java.time.format.DateTimeParseException: Text ‘2021-09-29 09:35:07.531’ could not be parsed at index 10.

So, how can I test if the given Instant date in String format is a valid Instant date?

I am implementing an Import feature and I need to check the date cells. So, the date is normally kept in Instant format in db and for this reason I need to check if the cell date value is a valid Instant date. So, if there is a more proper way, of course I can follow that approach.

I do not use the value, I just need to check if the date is a valid date.

Advertisement

Answer

Your Date-Time string does not have timezone information and therefore you can not parse it into an Instant without introducing a timezone. I recommend you parse it into LocalDateTime and use the same for DB work if it is supposed to be used independent of timezones.

Demo:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String args[]) {
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse("2021-09-29 09:35:07.531", dtfInput);
        System.out.println(ldt);
    }
}

Output:

2021-09-29T09:35:07.531

ONLINE DEMO

How to use LocalDateTime in JDBC?

Given below is a sample code to insert a LocalDateTime into columnfoo (which is of TIMESTAMP type):

PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, ldt);
st.executeUpdate();
st.close();

Given below is a sample code to retrieve a LocalDateTime from columnfoo:

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
    // Assuming the column index of columnfoo is 1
    LocalDateTime ldt = rs.getObject(1, LocalDateTime.class));
    System.out.println(ldt);
}
rs.close();
st.close();

In case you want to parse the given Date-Time string into Instant:

As described above, you need to introduce a timezone in order to parse it into an Instant.

Demo:

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String args[]) {
        // Change the ZoneId to the applicable one e.g. ZoneId.of("Etc/UTC")
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH)
                                        .withZone(ZoneId.systemDefault());

        Instant instant = Instant.from(dtfInput.parse("2021-09-29 09:35:07.531"));
        System.out.println(instant);
    }
}

Output in my timezone, Europe/London:

2021-09-29T08:35:07.531Z

ONLINE DEMO

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

Advertisement