[java] What is this date format? 2011-08-12T20:17:46.384Z

I have the following date: 2011-08-12T20:17:46.384Z. What format is this? I'm trying to parse it with Java 1.4 via DateFormat.getDateInstance().parse(dateStr) and I'm getting

java.text.ParseException: Unparseable date: "2011-08-12T20:17:46.384Z"

I think I should be using SimpleDateFormat for parsing, but I have to know the format string first. All I have for that so far is yyyy-MM-dd, because I don't know what the T means in this string--something time zone-related? This date string is coming from the lcmis:downloadedOn tag shown on Files CMIS download history media type.

This question is related to java date time format simpledateformat

The answer is


Not sure about the Java parsing, but that's ISO8601: http://en.wikipedia.org/wiki/ISO_8601


tl;dr

Standard ISO 8601 format is used by your input string.

Instant.parse ( "2011-08-12T20:17:46.384Z" ) 

ISO 8601

This format is defined by the sensible practical standard, ISO 8601.

The T separates the date portion from the time-of-day portion. The Z on the end means UTC (that is, an offset-from-UTC of zero hours-minutes-seconds). The Z is pronounced “Zulu”.

java.time

The old date-time classes bundled with the earliest versions of Java have proven to be poorly designed, confusing, and troublesome. Avoid them.

Instead, use the java.time framework built into Java 8 and later. The java.time classes supplant both the old date-time classes and the highly successful Joda-Time library.

The java.time classes use ISO 8601 by default when parsing/generating textual representations of date-time values.

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds. That class can directly parse your input string without bothering to define a formatting pattern.

Instant instant = Instant.parse ( "2011-08-12T20:17:46.384Z" ) ;

Table of date-time types in Java, both modern and legacy


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Table of which java.time library to use with which version of Java or Android


This technique translates java.util.Date to UTC format (or any other) and back again.

Define a class like so:

import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class UtcUtility {

public static DateTimeFormatter UTC = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZoneUTC();


public static Date parse(DateTimeFormatter dateTimeFormatter, String date) {
    return dateTimeFormatter.parseDateTime(date).toDate();
}

public static String format(DateTimeFormatter dateTimeFormatter, Date date) {
    return format(dateTimeFormatter, date.getTime());
}

private static String format(DateTimeFormatter dateTimeFormatter, long timeInMillis) {
    DateTime dateTime = new DateTime(timeInMillis);
    String formattedString = dateTimeFormatter.print(dateTime);
    return formattedString;
}

}

Then use it like this:

Date date = format(UTC, "2020-04-19T00:30:07.000Z")

or

String date = parse(UTC, new Date())

You can also define other date formats if you require (not just UTC)


You can use the following example.

    String date = "2011-08-12T20:17:46.384Z";

    String inputPattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    String outputPattern = "yyyy-MM-dd HH:mm:ss";

    LocalDateTime inputDate = null;
    String outputDate = null;


    DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(inputPattern, Locale.ENGLISH);
    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(outputPattern, Locale.ENGLISH);

    inputDate = LocalDateTime.parse(date, inputFormatter);
    outputDate = outputFormatter.format(inputDate);

    System.out.println("inputDate: " + inputDate);
    System.out.println("outputDate: " + outputDate);

@John-Skeet gave me the clue to fix my own issue around this. As a younger programmer this small issue is easy to miss and hard to diagnose. So Im sharing it in the hopes it will help someone.

My issue was that I wanted to parse the following string contraining a time stamp from a JSON I have no influence over and put it in more useful variables. But I kept getting errors.

So given the following (pay attention to the string parameter inside ofPattern();

String str = "20190927T182730.000Z"

LocalDateTime fin;
fin = LocalDateTime.parse( str, DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSZ") );

Error:

Exception in thread "main" java.time.format.DateTimeParseException: Text 
'20190927T182730.000Z' could not be parsed at index 19

The problem? The Z at the end of the Pattern needs to be wrapped in 'Z' just like the 'T' is. Change "yyyyMMdd'T'HHmmss.SSSZ" to "yyyyMMdd'T'HHmmss.SSS'Z'" and it works.

Removing the Z from the pattern alltogether also led to errors.

Frankly, I'd expect a Java class to have anticipated this.


If you guys are looking for a solution for Android, you can use the following code to get the epoch seconds from the timestamp string.

public static long timestampToEpochSeconds(String srcTimestamp) {
    long epoch = 0;

    try {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Instant instant = Instant.parse(srcTimestamp);
            epoch = instant.getEpochSecond();
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'", Locale.getDefault());
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date date = sdf.parse(srcTimestamp);
            if (date != null) {
                epoch = date.getTime() / 1000;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return epoch;
}

Sample input: 2019-10-15T05:51:31.537979Z

Sample output: 1571128673


There are other ways to parse it rather than the first answer. To parse it:

(1) If you want to grab information about date and time, you can parse it to a ZonedDatetime(since Java 8) or Date(old) object:

// ZonedDateTime's default format requires a zone ID(like [Australia/Sydney]) in the end.
// Here, we provide a format which can parse the string correctly.
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime zdt = ZonedDateTime.parse("2011-08-12T20:17:46.384Z", dtf);

or

// 'T' is a literal.
// 'X' is ISO Zone Offset[like +01, -08]; For UTC, it is interpreted as 'Z'(Zero) literal.
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

// since no built-in format, we provides pattern directly.
DateFormat df = new SimpleDateFormat(pattern);

Date myDate = df.parse("2011-08-12T20:17:46.384Z");

(2) If you don't care the date and time and just want to treat the information as a moment in nanoseconds, then you can use Instant:

// The ISO format without zone ID is Instant's default.
// There is no need to pass any format.
Instant ins = Instant.parse("2011-08-12T20:17:46.384Z");

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to date

How do I format {{$timestamp}} as MM/DD/YYYY in Postman? iOS Swift - Get the Current Local Time and Date Timestamp Typescript Date Type? how to convert current date to YYYY-MM-DD format with angular 2 SQL Server date format yyyymmdd Date to milliseconds and back to date in Swift Check if date is a valid one change the date format in laravel view page Moment js get first and last day of current month How can I convert a date into an integer?

Examples related to time

Date to milliseconds and back to date in Swift How to manage Angular2 "expression has changed after it was checked" exception when a component property depends on current datetime how to sort pandas dataframe from one column Convert time.Time to string How to get current time in python and break up into year, month, day, hour, minute? Xcode swift am/pm time to 24 hour format How to add/subtract time (hours, minutes, etc.) from a Pandas DataFrame.Index whos objects are of type datetime.time? What does this format means T00:00:00.000Z? How can I parse / create a date time stamp formatted with fractional seconds UTC timezone (ISO 8601, RFC 3339) in Swift? Extract time from moment js object

Examples related to format

Brackets.io: Is there a way to auto indent / format <html> Oracle SQL - DATE greater than statement What does this format means T00:00:00.000Z? How to format date in angularjs How do I change data-type of pandas data frame to string with a defined format? How to pad a string to a fixed length with spaces in Python? How to format current time using a yyyyMMddHHmmss format? java.util.Date format SSSSSS: if not microseconds what are the last 3 digits? Formatting a double to two decimal places How enable auto-format code for Intellij IDEA?

Examples related to simpledateformat

How to convert an Instant to a date format? Get Date Object In UTC format in Java How to format a java.sql.Timestamp(yyyy-MM-dd HH:mm:ss.S) to a date(yyyy-MM-dd HH:mm:ss) How to convert date to string and to date again? Java Convert GMT/UTC to Local time doesn't work as expected Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST SimpleDateFormat parse loses timezone java.text.ParseException: Unparseable date Java format yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss SimpleDateFormat returns 24-hour date: how to get 12-hour date?