Search code examples
javadatetimehtmldate-parsingrfc3339

How do I parse RFC 3339 datetimes with Java?


I'm trying to parse the date returned as a value from the HTML5 datetime input field. Try it in Opera to see an example. The date returned looks like this: 2011-05-03T11:58:01Z.

I'd like to parse that into a Java Date or Calendar Object.

Ideally a solution should have the following things:

  • No external libraries (jars)
  • Handles all acceptable RFC 3339 formats
  • A String should be able to be easily validated to see if it is a valid RFC 3339 date

Solution

  • Just found that google implemented Rfc3339 parser in Google HTTP Client Library

    https://github.com/google/google-http-java-client/blob/dev/google-http-client/src/main/java/com/google/api/client/util/DateTime.java

    Tested. It works well to parse varies sub seconds time fragment.

    import java.time.ZoneId;
    import java.time.format.DateTimeFormatter;
    import java.util.Date;
    
    import com.google.api.client.util.DateTime;
    
    DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
                .withZone(ZoneId.of("UTC"));
    
    @Test
    public void test1e9Parse() {
        String timeStr = "2018-04-03T11:32:26.553955473Z";
    
        DateTime dateTime = DateTime.parseRfc3339(timeStr);
        long millis = dateTime.getValue();
    
        String result = formatter.format(new Date(millis).toInstant());
    
        assert result.equals("2018-04-03T11:32:26.553Z");
    }
    
    @Test
    public void test1e3Parse() {
        String timeStr = "2018-04-03T11:32:26.553Z";
    
        DateTime dateTime = DateTime.parseRfc3339(timeStr);
        long millis = dateTime.getValue();
    
        String result = formatter.format(new Date(millis).toInstant());
    
        assert result.equals("2018-04-03T11:32:26.553Z");
    }
    
    @Test
    public void testEpochSecondsParse() {
    
        String timeStr = "2018-04-03T11:32:26Z";
    
        DateTime dateTime = DateTime.parseRfc3339(timeStr);
        long millis = dateTime.getValue();
    
        String result = formatter.format(new Date(millis).toInstant());
    
        assert result.equals("2018-04-03T11:32:26.000Z");
    }