Home > Enterprise >  Java Instant.parse cannot validate date
Java Instant.parse cannot validate date

Time:10-12

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?

CodePudding user response:

A reference to the time zone is mandatory if you are trying to use the Instant class. So, let's try this:

LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd H:mm:ss.SSS").parse("2021-09-29 09:35:07.351")).atZone(ZoneId.systemDefault()).toInstant();

CodePudding user response:

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.

CodePudding user response:

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

It is not.

An instant is a (unique) point in time. Your string holds a date and time of day. Without knowing the time zone this may denote some point within a range of 24 or 27 hours — so pretty far from being one point in time.

So instead use a format that includes offset from UTC. In particular the ISO 8601 format for an instant in UTC is a recommended option for several purposes, like 2021-09-29T01:35:07.531Z.

Link: Wikipedia article: ISO 8601

  • Related