656

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.

Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
  • 94
    It's [ISO 8601](http://en.wikipedia.org/wiki/ISO_8601) – Tomasz Nurkiewicz Dec 06 '11 at 18:47
  • 8
    ISO8601 doe allow a Z at the end. See the link above, look for UTC. – Jonathan Rosenne May 09 '15 at 09:53
  • 8
    @t1gor The `Z` at the end is short for `Zulu` and means [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time). This format most certainly *is* part of the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) collection of standard date-time text formats. By the way, these standard formats are used by default in the *java.time* classes. – Basil Bourque Jan 16 '18 at 22:26
  • 5
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 01 '18 at 17:46
  • Related: [*How to get the date and time in format 2022-10-03T19:45:47.844Z in Java*](https://stackoverflow.com/q/74356407/642706) – Basil Bourque Nov 09 '22 at 00:42

12 Answers12

736

The T is just a literal to separate the date from the time, and the Z means "zero hour offset" also known as "Zulu time" (UTC). If your strings always have a "Z" you can use:

SimpleDateFormat format = new SimpleDateFormat(
    "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));

Or using Joda Time, you can use ISODateTimeFormat.dateTime().

Jesús Barrera
  • 400
  • 1
  • 5
  • 15
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 14
    Why do we need the single quotes around `T` and `Z`? – Maroun Jun 03 '15 at 07:57
  • 12
    @MarounMaroun: Basically we want those *literal* characters. It may not be necessary for `T` (I can't remember how SimpleDateFormat handles unknown specifiers) but for `Z` we want it to be the character 'Z' rather than "a UTC offset value" (e.g. "00"). – Jon Skeet Jun 03 '15 at 08:23
  • java.lang.IllegalArgumentException: Illegal pattern character 'T' If you don't use single quotes around T or Z SimpleDateFormat throws this exception. – user989383 Jan 22 '16 at 07:41
  • @user989383: Are you sure you quoted it as I did (with the apostrophes)? It should be absolutely fine. – Jon Skeet Jan 22 '16 at 07:41
  • @JonSkeet: Hi John, I have this date and I wish to get a pattern of this date to convert it to another format :`2017-03-10T06:00:00.000+11:00` PLEASE HELP – Jad Chahine Sep 21 '16 at 18:41
  • 1
    @JadChahine: So have you done a search for questions about converting date/time values from one format to another? There are *hundreds* (if not thousands) of similar questions on SO. – Jon Skeet Sep 21 '16 at 18:41
  • @JonSkeet: Yes really i search a lot but I don't found a format that takes into account the last characters of this date format which is `+11:00` – Jad Chahine Sep 21 '16 at 18:43
  • @JadChahine: Well that's the offset from UTC. So look in the documentation for `SImpleDateFormat`... and then you need to work out which time zone you're actually interested in. – Jon Skeet Sep 21 '16 at 18:48
  • Point of correction please *(for clarity)*: the ***Z*** is the zone designator for the *zero **UTC** offset* and does not means ***"Zulu time"***. Reference is made to [***Zulu time***](https://en.wikipedia.org/wiki/List_of_military_time_zones) as ***Zulu*** is the [***NATO phonetic alphabet***](https://en.wikipedia.org/wiki/NATO_phonetic_alphabet) word for letter [***Z***](https://en.wikipedia.org/wiki/Z) *(26th letter of the English alphabet)*. – nyedidikeke Nov 12 '16 at 11:28
  • 2
    @nyedidikeke: In the Wikipedia page you linked to, it shows "Zulu time zone" for UTC. I'm not sure what you believe you're correcting. – Jon Skeet Nov 12 '16 at 22:22
  • 11
    @JonSkeet: it may generate an unnecessary debate; not disputing your answer but intended to draw attention the ***Z*** which got its letter initial from "zero UTC offset". Letter Z is referred to as "Zulu" in the **NATO phonetic alphabet**. In turns, the military approach to refer to the zero UTC offset is anchored on letter Z which they identify as Zulu, earning it their coded name: Zulu time zone. It is important to note that the Z has not lost its meaning and still is the zone designator for the zero UTC offset as Zulu time zone (from Z) is simply an inherited coded language to refer to it. – nyedidikeke Nov 12 '16 at 23:55
  • 4
    @nyedidikeke: I still disagree about whether anyone else is ever going to care about the distinction with reference to my answer, but I've updated it. I'm not going to go into all the detail though, as the history is broadly irrelevant to the answer. – Jon Skeet Nov 13 '16 at 07:42
  • You can test this date pattern online: http://dateformatter.danielhari.com/?p=yyyy-MM-dd%27T%27HH%3Amm%3Ass.SSS%27Z%27 – Daniel Hári Mar 02 '17 at 12:46
  • Good Answer, but now outdated. The java.time classes supplant both the legacy date-classes bundled with the earliest versions of Java as well as the Joda-Time project. – Basil Bourque Nov 06 '17 at 04:46
  • 1
    @Basil: Yes, but I'm not going to go and edit every answer from years ago to use java.time. As the question specifically talks about Java 1.4, I think it stands reasonably to answer that specific question. – Jon Skeet Nov 06 '17 at 06:25
  • Note that `setTimeZene` is very important as Z means the zero offset from this timezone. – CodeBrew Dec 18 '18 at 17:15
  • 1
    @CodeBrew: Not "from this time zone" but from UTC. – Jon Skeet Dec 18 '18 at 18:04
  • @JonSkeet at first I didn't `setTimeZone` to UTC, then my date formatter converted a date string in the format like `2011-08-12T15:17:46.384Z` to `2011-08-12T20:17:46.384Z`, effectively thinking the original string I gave was in my own timezone (EST). Once I `setTimeZone` to UTC the converted result became correct. Of course I was using Swift, but the syntax is close to what you posted here. Could you try it in Java without `setTimeZone` and compare the difference? Thanks – CodeBrew Dec 19 '18 at 03:00
  • 1
    @CodeBrew: I wasn't saying that the call to `setTimeZone` wasn't required. It absolutely is. I'm saying that Z doesn't mean "the zero offset from this time zone" - it means "UTC" (or "zero offset from UTC" if you want). – Jon Skeet Dec 19 '18 at 06:51
  • 2023-02-14T17:53:01.4447335 <- I have this time, does anyone know which format is this ? , no z at the end but accurate to more milliseconds – Sithija Piyuman Thewa Hettige Feb 15 '23 at 07:29
  • @SithijaPiyumanThewaHettige: Please don't use comment threads to get answers to new questions. – Jon Skeet Feb 15 '23 at 07:41
183

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

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 5
    @star The “Zulu” comes from military and aviation tradition where 25 letters of the alphabet A-Z (no "J"), each letter having a pronounceable name, represents [their version of time zones](https://en.wikipedia.org/wiki/List_of_military_time_zones). The "Zulu" zone is zero hours offset from UTC. See [this](https://www.timeanddate.com/time/zones/z) and [this](https://en.wikipedia.org/w/index.php?title=Coordinated_Universal_Time&mobileaction=toggle_view_desktop#Time_zones). – Basil Bourque Nov 06 '17 at 04:35
  • the LocalDateTime.parse("2021-11-22T09:00:00.000Z") throws exception while parsing. Any suggestion, how to format the same input using `java.time` to format to "EEEE, MMMM dd"? thanks. – Faisal Oct 04 '21 at 12:06
  • @Faisal Your attempt to parse a moment (a date with time and offset) as a `LocalDateTime` is illogical. A `LocalDateTime` is not a moment, not a specific point on the timeline, because it has no concept of an offset-from-UTC nor time zone. Your input should be parsed as an `Instant`, like this: `Instant.parse("2021-11-22T09:00:00.000Z")`. – Basil Bourque Oct 04 '21 at 16:43
  • Make sense. Can an Instance be parsed to expected format? – Faisal Oct 06 '21 at 10:03
  • @Faisal Apply a time zone (`ZoneId`) through which you want to perceive a date. This gets you a `ZonedDateTime`. Extract from that a `LocalDate`. Use a `DateTimeFormatter` to generate text in any format you desire, or automatically localize. All that has been covered many times already on Stack Overflow. – Basil Bourque Oct 06 '21 at 15:26
29

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

smparkes
  • 13,807
  • 4
  • 36
  • 61
  • Is this "2016-01-27T17:44:55UTC", ISO8601 too ? – user1997292 Jan 28 '16 at 09:55
  • I don't believe so. It's close but _UTC_ as a suffix isn't allowed. It has to be Z or a time zone offset, e.g., +0100. Z and UTC have the same meaning, though, so changing the _UTC_ to _Z_ would yield valid ISO 8601. – smparkes Jan 28 '16 at 13:41
  • @user1997292 No. In ISO 8601 UTC can be indicated as `Z`, `+00:00`, `+0000` or `+00`. – Ole V.V. Apr 20 '23 at 19:58
14

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");
VeryLazyBoy
  • 400
  • 3
  • 13
10

java.time

You do not need DateTimeFormatter to parse the given date-time string.

Java SE 8 Date-Time API(java.time API or the modern Date-Time API) is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.

The Z in the string is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).

The T in the string is just the Date-Time separator as per the ISO-8601 standards.

Demo:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-08-12T20:17:46.384Z";

        Instant instant = Instant.parse(strDateTime);
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime);
        
        System.out.println(instant);
        System.out.println(odt);
        System.out.println(zdt);
    }
}

Output:

2011-08-12T20:17:46.384Z
2011-08-12T20:17:46.384Z
2011-08-12T20:17:46.384Z

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

The legacy Date-time API

The legacy Date-time API (java.util Date-Time API and their formatting API, SimpleDateFormat) are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

For the sake of completeness, I've written a solution to parse this Date-Time string using the legacy API.

Do not use 'Z' in the pattern with the Date-Time parsing/formatting API.

As already described above, Z (without quotes) is the timezone designator for zero-timezone offset whereas 'Z' is just a character literal and it does not hold any meaning. Use the format, y-M-d'T'H:m:s.SSSXXX. Check the documentation to learn more about these symbols.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        String strDateTime = "2011-08-12T20:17:46.384Z";

        SimpleDateFormat sdf = new SimpleDateFormat("y-M-d'T'H:m:s.SSSXXX", Locale.ENGLISH);
        Date date = sdf.parse(strDateTime);
        // ...
    }
}

Note that a java.util.Date object is not a real Date-Time object like the modern Date-Time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any format and timezone information, it applies the format, EEE MMM dd HH:mm:ss z yyyy and the JVM's timezone to return the value of Date#toString derived from this milliseconds value. If you need to print the Date-Time in a different format and timezone, you will need to use a SimpleDateFormat with the desired format and the applicable timezone e.g.

sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String formatted = sdf.format(date);
System.out.println(formatted); // 2011-8-12T20:17:46.384Z

Joda Date-Time API

Quoted below is a notice at the Home Page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Again, for the sake of completeness, I've written a solution to parse this Date-Time string using the Joda Date-Time API.

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

public class Main {
    public static void main(String[] args) {
        String dateTimeStr = "2011-08-12T20:17:46.384Z";
        DateTimeFormatter dtf = DateTimeFormat.forPattern("y-M-d'T'H:m:s.SSSZ").withOffsetParsed();
        DateTime dateTime = dtf.parseDateTime(dateTimeStr);
        System.out.println(dateTime);
    }
}

Output:

2011-08-12T20:17:46.384Z

* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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 and How to use ThreeTenABP in Android Project.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
4

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

rahulrvp
  • 2,006
  • 1
  • 19
  • 26
3

Z represent UTC time zone. With java8+, you can simply use Instant.

public static void main(String[] args) {
    String time = "2022-06-08T04:55:01.000Z";
    System.out.println(Instant.parse(time).toEpochMilli());
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Mayank PATEl
  • 113
  • 2
  • 6
2

In JavaScript

let isoDateTimeString = new Date().toISOString();

Description

Date/time format like "YYYY-MM-DDThh:mm:ss.SSSZ" is ISO 8601 date/time format.

Firma 777
  • 21
  • 2
0

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);
  • 1
    You should not be putting apostrophes around the `Z`. That means to expect but ignore that letter. But that letter should not be ignored. That letter provides valuable information, the fact that the string was intended for UTC, an offset of zero. Your format is discarding this important fact. Furthermore, there is no need to even bother defining this formatting pattern. A formatter for this pattern is built in. – Basil Bourque Sep 24 '19 at 05:37
0

FOR JODA TIME

String datetimeString = "2099-12-31T14:20:04Z";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZoneUTC();
DateTime dateTime = formatter.parseDateTime(datetimeString);
System.out.println("Parsed date and time: " + dateTime);
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Lijo
  • 6,498
  • 5
  • 49
  • 60
  • No need to fiddle with your own format pattern string since Joda-Time knows ISO 8601 format well. And never hard-code `Z` as a literal in the format. It’s the offset and needs to be parsed as an offset. Use for example `ISODateTimeFormat.dateTimeParser() .withOffsetParsed() .parseDateTime(datetimeString)` (yields `Parsed date and time: 2099-12-31T14:20:04.000Z`). – Ole V.V. Apr 20 '23 at 19:51
-1

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)

Gapmeister66
  • 846
  • 9
  • 14
  • Both `java.util.Date` and the *Joda-Time* project were supplanted years ago by the modern *java.time* classes defined in JSR 310. The advice here is long outdated. – Basil Bourque May 09 '19 at 15:25
  • java.time was introduced in Java 8. This question specifically references Java 1.4 and therefore I have deliberately avoided use of the newer classes. This solution caters for older code bases. I suppose the author could move his codebase to Java 8 but that is not always straightforward, efficient or necessary. – Gapmeister66 Oct 04 '19 at 14:20
-1

@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.

spencemw
  • 131
  • 1
  • 3
  • 10
  • 2
    This has already been asked and answered [here](https://stackoverflow.com/questions/52480189/parse-date-string-in-java) and [here](https://stackoverflow.com/questions/57325267/zoneddatetime-ignore-00-for-ss-part). And your solution is wrong. While `T` is a literal and needs to be quoted, `Z` is an offset (of zero) and needs to be parsed as such, or you will get wrong results. I don’t know what you mean that it hasn’t been anticipated, I believe that it has. – Ole V.V. Sep 27 '19 at 10:55
  • 2
    No, no, no, do not ignore the `Z`. You are discarding valuable information. Processing a date-time value while ignoring time zone or offset-from-UTC is like processing an amount of money while ignoring currency! – Basil Bourque Sep 27 '19 at 16:59
  • 2
    The `T` merely separates the date portion from the time-of-day portion, and adds no meaning. The `Z` on the other hand definitely adds meaning. – Basil Bourque Sep 27 '19 at 17:02
  • Ole, thanks for the links. Ill certainly read those. And I accept that I certainly could be wrong as a youngin. All Im saying is that wrapping the Z in single quotes like a char in the pattern solved the error. My criticism is that whoever designed "pattern" part of the class could have coded around the presence or absence of 'Z' (or a diff time zone?) and 'T' being wraped in ' ' or not. Because they didnt its unique. The format Im dealing with comes from JSON from a commercial API parsed to a string. But I need to parse all that into date time calendar etc to make them more useful. – spencemw Sep 28 '19 at 00:20