XMLGregorianCalendar date format 'dd/MM/yyyy HH:mm:ss.SSS' - java

String formatA ="yyyy-MM-dd'T'HH:mm:ss'Z'";
String formatB = "dd/MM/yyyy HH:mm:ss.SSS";
try {
XMLGregorianCalendar gregFmt = DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat(formatB).format(new Date()));
System.out.println(gregFmt);
} catch (DatatypeConfigurationException e) {
};
I am trying to formate XMLGregorianCalendar date .
The above code formats well for format "yyyy-MM-dd'T'HH:mm:ss'Z'"
But for formatB dd/MM/yyyy HH:mm:ss.SSS it throws error
java.lang.IllegalArgumentException
Do advice on how to fix it. Thank you so much!
log
Exception in thread "main" java.lang.IllegalArgumentException: 23/08/2017 16:13:04.140
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parseAndSetYear(XMLGregorianCalendarImpl.java:2887)
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2773)
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:435)
at com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:536)
at test.test.main(test.java:19)
line19 is line 4 , in the above code 'XMLGregorianCalendar gregFmt...'

The format that newXMLGregorianCalendar(string) accept is described in the XML specs and is different from the formatB you are trying to use.

tl;dr
Date-time objects do not have a “format”. They parse & generate String objects representing textually their value.
Use the modern java.time that replaced terrible old classes Date & XMLGregorianCalendar classes.
Example:
myXMLGregorianCalendar // If you must use this class… but try to avoid. Use *java.time* classes instead.
.toGregorianCalendar() // Converting from `javax.xml.datatype.XMLGregorianCalendar` to `java.util.GregorianCalendar`.
.toZonedDateTime() // Converting from `java.util.GregorianCalendar` to `java.time.ZonedDateTime`, from legacy class to modern class.
.format( // Generate a `String` representing the moment stored in our `ZonedDateTime` object.
DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss.SSS" ) // Define a formatting pattern as you desire. Or better, automatically localize by calling `DateTimeFormatter.ofLocalized…` methods.
) // Returns a `String` object, distinct from our `ZonedDateTime` object.
07/07/2018 15:20:14.372
Date-time objects do not have a format
Do not conflate date-time objects with the strings they generate to represent their value. Date-time values, including the classes discussed below, are not a String, do not use text as their internal value, and do not have a “format”. All of them can generate, and parse, strings to represent their date-time value.
java.time
The modern approach uses the java.time classes that supplanted the troublesome old legacy date-time classes such as XMLGregorianCalendar.
The use of java.util.Date should be replaced with java.time.Instant. Both represent a moment in UTC. Instant uses a finer resolution of nanoseconds rather than milliseconds.
You can easily convert between the modern and legacy classes. Notice the new conversion methods added to the old classes, in this case java.util.GregorianCalendar::toZonedDateTime.
First convert from javax.xml.datatype.XMLGregorianCalendar to java.util.GregorianCalendar.
GregorianCalendar gc = myXMLGregorianCalendar.toGregorianCalendar() ;
Now get out of these legacy classes, and into java.time.
ZonedDateTime zdt = gc.toZonedDateTime() ;
All three types so far, the XMLGregorianCalendar, the GregorianCalendar, and the ZonedDateTime all represent the same moment, a date with time-of-day and an assigned time zone.
With a ZonedDateTime in hand, you can generate a String in standard ISO 8601 format extended to append the name of the time zone in square brackets.
String output = zdt.toString() ; // Generate string in standard ISO 8601 format extended by appending the name of time zone in square brackets.
2018-07-07T15:20:14.372-07:00[America/Los_Angeles]
You can generate strings in other formats using DateTimeFormatter class. For the formatting pattern listed second in your question, define a matching DateTimeFormatter object.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss.SSS" ) ;
String output = zdt.format( f ) ;
07/07/2018 15:20:14.372
The first formatting pattern listed in your Question has a Z on the end, which means UTC and is pronounced “Zulu”. To adjust our ZonedDateTime to UTC, simply extract a Instant object. An Instant is always in UTC by definition.
Instant instant = zdt.toInstant() ; // Extract an `Instant` object, always in UTC.
Generate a String in the pattern shown first in the Question.
String output = instant.toString() ; // Generate string in standard ISO 8601 format.
2018-07-07T22:20:14.372Z
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Related

Parse timestamp string to Java.sql.timestamp [duplicate]

This question already has answers here:
Converting ISO 8601-compliant String to java.util.Date
(31 answers)
Java: Convert String to TimeStamp
(11 answers)
Closed 3 years ago.
I have the following timestamp in String format
2019-04-06T00:43:21+00:00
2019-04-04T21:24:33+00:00
2019-04-04T21:02:16+00:00
How can I parse the timestamp strings above to Java.sql.timestamp?
Use DateFormat to parse your String.
try{
String x="2019-04-04T21:24:33+00:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssX");
Date date = (Date) df.parse(x);
java.sql.Timestamp timeStamp = new java.sql.Timestamp(date.getTime());
}catch(ParseException pe){
pe.printStackTrace();
}
As mentioned by others in comments, there is a more updated way to do this.
String time="2019-04-04T21:02:16+00:00";
OffsetDateTime odt=OffsetDateTime.parse(time,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
java.sql.Timestamp timestamp=new java.sql.Timestamp(odt.toEpochSecond()*1000);
tl;dr
Timestamp // Avoid this terrible legacy class if possible. Represents a moment in UTC.
.from( // Convert from modern `Instant` to legacy `Timestamp`. No data loss, as both resolve to nanoseconds.
OffsetDateTime // Modern way to represent a moment with an offset-from-UTC (hours, minutes, and seconds).
.parse( "2019-04-06T00:43:21+00:00" ) // Parse standard ISO 8601 strings. Returns a `java.time.OffsetDateTime` object.
.toInstant() // Extract an `Instant` from the `OffsetDateTime`, thereby adjusting to UTC (an offset of zero).
) // Returns a `Timestamp` object, if needed to interoperate with old code not yet updated to *java.time*.
Even better, skip the terrible Timestamp class entirely.
myPreparedStatement.setObject( // As of JDBC 4.2 and later, exchange *java.time* objects with your database.
1 , // Specify the nth placeholder in your SQL statement.
OffsetDateTime.parse( "2019-04-06T00:43:21+00:00" ) // Parse an ISO 8601 compliant string as a `OffsetDateTime` object, a moment with an offset-from-UTC. Pass to the database via the `setObject` call.
)
OffsetDateTime
Your input strings indicate an offset-from-UTC (a number of hours-minutes-seconds), that part at the end.
Your input strings are in standard ISO 8601 format. The java.time classes use these formats by default in parsing/generating strings. So no need to specify a formatting pattern.
OffsetDateTime odt = OffsetDateTime.parse( "2019-04-06T00:43:21+00:00" ) ;
java.sql.Timestamp
Never use java.util.Timestamp. That terrible class was supplanted years ago by the modern java.time classes.
If you must have a Timestamp object to interoperate with old code not yet updated to java.time, convert by calling new methods added to the old classes. Extract a Instant from the OffsetDateTime (thereby adjusting from any offset to an offset of zero, for UTC itself). Pass the Instant object to Timestamp.from.
java.sql.Timestamp ts = Timestamp.from( odt.toInstant() ) ;
JDBC 4.2
As of JDBC 4.2, we can exchange java.time objects with the database.
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
All this has been covered many many times already on Stack Overflow. So search for more info. And in the future, search thoroughly before posting.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Converting time to UTC time goes the opposite way

I'm trying to parse an offset time using Java 8 DateTimeFormatter.
I live in EST time which is UTC-5, so when I try to convert
2019-01-22T13:09:54.620-05:00 should be --> 2019-01-22T18:09:54.620
However, with my code, it gets the current time and goes back 5 hours, resulting in 2019-01-22 08:09:54.620
Code:
import java.sql.Timestamp
import java.time._
import java.time.format.DateTimeFormatter
import scala.util.{Failure, Success, Try}
class MyTimeFormatter(parser: DateTimeFormatter) {
def parse(input: String): Try[Timestamp] = {
Try(new Timestamp(Instant.from(parser.withZone(ZoneOffset.UTC).parse(input)).toEpochMilli))
}
}
Test:
new MyTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx")).parse("2019-01-22T13:09:54.620-05:00") shouldEqual Timestamp.valueOf("2019-01-22T18:09:54.620")
where parser is of type DateTimeFormatter and input string is just "2019-01-22T13:09:54.620-05:00"
I want to use this parser.parse method and not with specific temporalAccessors like OffsetDateTime.parse(input, parser) so I can handle all cases like LocalTime, LocalDateTime, ZonedDateTime, OffsetDateTime, etc..
It seems like the code just grabs the time, subtracts the offset, and brands it as UTC instead of calculating the offset with respect to UTC.
Also, is there a way to apply this UTC conversion only if the input format is of ZonedDateTime/OffsetDateTime format? If I input a LocalDateTime (which doesn't have an offset) such as 2017-01-01 12:45:00 the parser will still apply the UTC offset conversion because I told the parser to parse with zone UTC.
tl;dr
Use modern java.time classes. Convert to legacy class only if necessary to work with old code.
Specifically, parse your input string as a OffsetDateTime object, adjust to UTC by extracting an Instant, and lastly, convert to java.sql.Timestamp (only if you must).
java.sql.Timestamp ts = // Avoid using this badly-designed legacy class if at all possible.
Timestamp // You can convert back-and-forth between legacy and modern classes.
.from( // New method added to legacy class to convert from modern class.
OffsetDateTime // Represents a moment with an offset-of-UTC, a number of some hours-minutes-seconds ahead or behind UTC.
.parse( "2019-01-22T13:09:54.620-05:00" ) // Text in standard ISO 8601 format can be parsed by default, without a formatting pattern.
.toInstant() // Adjust from an offset to UTC (an offset of zero) by extracting an `Instant`.
) // Returns a `Timestamp` object. Same moment as both the `OffsetDateTime` and `Instant` objects.
;
See this code run live at IdeOne.com, resulting in:
ts.toString(): 2019-01-22 18:09:54.62
If using JDBC 4.2 or later, skip the Timestamp altogether.
myPreparedStatement.setObject( … , myOffsetDateTime ) ;
Zulu
2019-01-22T13:09:54.620-05:00 should be --> 2019-01-22T18:09:54.620
If you meant that second value to represent a moment in UTC, append the offset-from-UTC to indicate that fact. Either +00:00 or Z (pronounced “Zulu”): 2019-01-22T18:09:54.620Z.
Reporting a moment without an offset-from-UTC or time zone indicator is like reporting an amount of money without a currency indicator.
OffsetDateTime
A string with an offset-from-UTC should be parsed as a OffsetDateTime object.
Your input string happens to comply with the ISO 8601 standard formats for textual date-time values. The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
OffsetDateTime odt = OffsetDateTime.parse( "2019-01-22T13:09:54.620-05:00" ) ;
Timestamp
Apparently you want a java.sql.Timestamp object. This is one of the terrible date-time classes bundled with the earliest versions of Java. These classes are now legacy, supplanted entirely by the modern java.time classes with the adoption of JSR 310. Avoid these legacy classes whenever possible.
If you must have a Timestamp to interoperate with old code not yet updated to work with java.time, you can convert. To convert, call new methods added to the old classes.
Instant
The java.sql.Timestamp class carries a from( Instant ) method. An Instant is a moment in UTC. To adjust from the offset of our OffsetDateTime to UTC, just extract an Instant.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = Timestamp.from( instant ) ;
We have three objects ( odt, instant, & ts ) that all represent the same moment. The first has a different wall-clock time. But all three are the same simultaneous point on the timeline.
JDBC 4.2
As of JDBC 4.2, we can directly exchange java.time objects with the database. So no need to use Timestamp.
myPreparedStatement.setObject( … , odt ) ;
…and…
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
While I cannot reproduce your issue precisely (even with changing my clock to EST), this is what I am observing:
Instant instant = Instant.from(parser.withZone(ZoneOffset.UTC).parse("2019-01-22T13:09:54.620-05:00"));
This is producing the time you would expect (2019-01-22T18:09:54.620Z).
Timestamp ts = new Timestamp(instant.toEpochMilli());
Because this is based on java.util.Date, which displays as your local time.
A better way to convert an Instant to a Timestamp is via the LocalDateTime, like so:
Timestamp ts = Timestamp.valueOf(instant.atZone(ZoneOffset.UTC).toLocalDateTime());

Parsing ISO 8601 date format like 2015-06-27T13:16:37.363Z in Java [duplicate]

This question already has answers here:
Java / convert ISO-8601 (2010-12-16T13:33:50.513852Z) to Date object
(4 answers)
Closed 6 years ago.
I am trying to parse a String using SimpleDateFormat.
This is my current code:
public String getCreatedDateTime() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-ddEHH:mm:ss.zzzz");
try {
Date date = simpleDateFormat.parse("2015-06-27T13:16:37.363Z");
return date.toString();
} catch (ParseException e) {
return "Error parsing date";
}
}
As you can see, I just put a constant in the parse() method for testing purposes.
So, this is what I am trying to parse:
2015-06-27T13:16:37.363Z
This is the SimpleDateFormat pattern that I am using:
yyyy-MM-ddEHH:mm:ss.zzzz
I keep getting the ParseException.
I know that it is proably because of the .zzzz at the end but I have no idea what .363Z might stand for so I just used some random letters. Bad idea.
I'll appreciate your help a lot. Thank you!
Try with this pattern (note the X at the end and the 'T' in the middle):
"yyyy-MM-dd'T'HH:mm:ss.SSSX"
From Java's SimpleDateFormat's documentation:
ISO 8601 Time zone:
...
For parsing, "Z" is parsed as the UTC time zone designator.
And, from the part where it describes the different characters:
X - Time zone - ISO 8601 time zone
EDIT
If using Android, then "X" is not supported.
You can use this pattern (note Z is a literal now):
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
But then you'll get the date on your current timezone and would need to convert it to UTC if needed.
tl;dr
Skip the formatting pattern. Standard ISO 8601 format is used by default.
Instant.parse( "2015-06-27T13:16:37.363Z" )
ISO 8601
Your string format is formally defined by the ISO 8601 standard.
Basically your Question is a duplicate of this one, Converting ISO 8601-compliant String to java.util.Date.
Alternatives
The Answer by eugenioy is correct.
But you should know that the old java.util.Date/.Calendar/java.text.SimpleDateFormat classes bundled with Java are notoriously troublesome and should be avoided.
Outmoded Classes
Those old classes are now outmoded, first by the third-party Joda-Time library, and now by the new java.time package (Tutorial) built into Java 8 and later (inspired by Joda-Time, defined by JSR 310, extended by the ThreeTen-Extra project).
Both java.time and Joda-Time use the ISO 8601 standard as their defaults when parsing/generating string representations of date-time values. So the code is simple, no need for custom formatter objects. No need for all that format twiddling that caused your Exception.
Time Zone
Both java.time and Joda-Time have a zoned date-time class that understands its assigned time zone (unlike java.util.Date). If you do not assign one, the JVM’s current default time zone is assigned.
Beware that the JVM’s current default time zone can change at any time. It can change at deployment, defaulting to whatever the host OS setting is. And it can change at any moment during runtime when any code in any thread of any app within the JVM calls TimeZone.setDefault. So better to explicitly assign a desired/expected time zone.
java.time
The Z on the end of your string is short for Zulu and means UTC. The Instant class can directly parse that format, to represent a moment on the timeline in UTC with a resolution in nanoseconds.
String input = "2015-06-27T13:16:37.363Z";
Instant instant = Instant.parse( input );
Change the time zone from UTC to some desired/expected time zone.
ZoneID zone = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontréal = instant.atZone( zone ) ;
If you really need a java.util.Date for interoperability, convert.
java.util.Date utilDate = Date.from( zdtMontréal.toInstant() ) ;
Joda-Time
The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes:
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.
Example code using Joda-Time 2.8.1.
String input = "2015-06-27T13:16:37.363Z" ;
DateTimeZone zone = DateTimeZone.UTC ; // Or: DateTimeZone.forID( "America/Montreal" ) ;
DateTime dateTime = new DateTime( input, zone ) ;
If you really need a java.util.Date for interoperability, convert.
java.util.Date date = dateTime.toDate();
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Formatting ISO 8601 date with a colon seperator

I am trying to convert the date in milliseconds to the following ISO 8601 format:
But I am getting the following using SimpleDateFormat:
/**
* It converts the time from long to the ISO format
*
* #param timestampMillis
* #return isoDate
*/
public String convertTimeMillisToISO8601(String timestampMillis)
{
long timeInLong= Long.parseLong(timestampMillis);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String isoDate = df.format(new java.util.Date(timeInLong));
return isoDate;
}
OUTPUT:
"ts":"2015-06-18T09:56:21+0000"
I know I can use substring to append the extra colon but Is there any better way to do so ?
For Java 7 and higher, you might use XXX (ISO 8601 time zone) in the date format String. According to the documentation, the result of X can be:
X => -08
XX => -0800
XXX => -08:00
but for all of those, it might as well return Z!
For Java 6 and earlier, there is no X (J6 doc), and since the result of X may or may not do what you want, I strongly recommend you just insert that colon yourself.
You can always use a StringBuilder:
new StringBuilder(
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.format(date))
.insert(22,':')
.toString();
For Java 8 if you use one of the standard ISO_DATE_* format patterns then the output formatted String will be truncated when the offset is +00:00 (UTC typically just appends Z).
OffsetDateTime utcWithFractionOfSecond = ZonedDateTime.parse("2018-01-10T12:00:00.000000+00:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
utcWithFractionOfSecond.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // 2018-01-10T12:00:00Z ... not what you want!
The only solution I have found is using the outputPattern (shown below) that uses lowercase `xxx' to ensure that a colon is included in the timezone offset.
I have included an example with factions-of-a-second for completeness (you can remove the SSSSSS in your case)
DateTimeFormatter inputPattern = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx");
OffsetDateTime utcWithFractionOfSecond = OffsetDateTime.parse("2018-01-10T12:00:00.000000+00:00", inputPattern);
OffsetDateTime utcNoFractionOfSecond = OffsetDateTime.parse("2018-01-10T12:00:00+00:00", inputPattern);
OffsetDateTime utcWithZ = OffsetDateTime.parse("2018-01-10T12:00:00Z", inputPattern);
OffsetDateTime utcPlus3Hours = OffsetDateTime.parse("2018-01-10T12:00:00.000000+03:00", inputPattern);|
utcWithFractionOfSecond.format(outputPattern ); // 2018-01-10T12:00:00.000000+00:00
utcNoFractionOfSecond.format(outputPattern); // 2018-01-10T12:00:00.000000+00:00
utcWithZ.format(outputPattern); // 2018-01-10T12:00:00.000000+00:00
utcPlus3Hours.format(outputPattern); // 2018-01-10T12:00:00.000000+03:00
In these examples I have used ISO_OFFSET_DATE_TIME only to create the input values for the test cases. In all cases it is the outputPattern yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx that controlling how to include a colon character in the timezone portion of your resulting formatted string.
Note that if your input data included the Zone ID like [Europe/London] then you would create your input data using ZonedDateTime instead of OffsetDateTime
Can you use Java 8?
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ssXXX");
System.out.println(formatter.format(ZonedDateTime.now()));
2015-04-15T17:24:19+09:00
tl;dr
OffsetDateTime.parse( "2014-06-18T09:56:21+00:00" )
2014-06-18T09:56:21Z
Details
Some other answers are close, correct in using the modern java.time classes that supplanted the terrible old legacy classes (Date, Calendar, SimpleDateFormat). But they are either working too hard or chose the wrong class.
ISO 8601
Your format is in standard ISO 8601 format. The java.time classes use these standard formats by default when parsing/generating text representing their date-time values. So you need not specify any formatting pattern at all. Works by default.
OffsetDateTime
Your input indicates an offset-from-UTC of zero hours and zero minutes. So we should use the OffsetDateTime class.
String input = "2014-06-18T09:56:21+00:00";
OffsetDateTime odt = OffsetDateTime.parse( input );
Zulu time
We can generate a string in standard ISO 8601 format by merely calling toString. The Z on the end means UTC, and is pronounced “Zulu”.
odt.toString(): 2014-06-18T09:56:21Z
ZonedDateTime
If your input indicated a time zone, rather than merely an offset, we would have used ZonedDateTime class. An offset is simply a number of hours, minutes, and seconds – nothing more. A time zone is much more. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

How to convert string to date object?

String date="2006-06-21T15:57:24.000Z";
How do I convert this String to a Date object without changing this format in Android?
Here simple code for this:
private Date parseDate(String date) {
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.S'Z'");
Date dateObj = new Date();
try {
dateObj = curFormater.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return dateObj;
}
Use the Time class and parse the string. Then use the Time toMillis() function and instantiate a Date.
http://developer.android.com/reference/android/text/format/Time.html#parse3339(java.lang.String)
See SimpleDateFormat, http://developer.android.com/reference/java/text/SimpleDateFormat.html
This class converts Strings to Dates and vice versa, using a given pattern.
Once you have created a SimpleDateFormat with the right pattern, you can use it to convert the string to a Date, use the date as you like, and eventually convert the Date back to a String using that same SimpleDateFormat instance.
EDIT: clarification on time zones
In the question it is not specified wether the given string is a "pure" ISO 8601 date, and in that case whether you need or not to support multiple time zones, if that timezones will be represented as only numbers (+0200 as in RFC 822), numbers with a colon (+02:00 as permitted by ISO 8601) or as names (EST etc...).
In case the string is a pure ISO 8601 String, then SimpleDateFormat will have some problems decoding the time zone. If however it is "always Z" (meaning that timezone data is not meaningful and you can safely ignore it), or uses numbers without colon (like +0200 etc..), or uses time zone names, then SimpleDateFormat can handle it correctly.
I came here because this was supposedly an answered question of Covert RFC3339 DateTime to Date in java. However, Time is a deprecated class in Android since API level 22.
A simple answer is based on this one:
import com.google.api.client.util.DateTime;
Date date = new Date(new DateTime("2006-06-21T15:57:24.000Z").getValue());
tl;dr
How do I convert this String to a Date object
Date is supplanted by java.time.Instant.
Instant.parse( "2006-06-21T15:57:24.000Z" )
without changing this format
Date-time objects do not have a “format”. Only text has a format.
String output = instant.toString() ; // Generate text in a `String` object in standard ISO 8601 format that represents the value of the `Instant` date-time object.
ISO 8601
That input string happens to be in standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.
java.time
The java.time classes use ISO 8601 formats by default when parsing and generating strings that represent date-time values.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.parse( "2006-06-21T15:57:24.000Z" );
To generate a String in standard ISO 8601 format, call toString.
String output = instant.toString();
2006-06-21T15:57:24Z
String != date-time
Do not conflate a date-time object with a String representing the value. The date-time object can parse a String, and can generate a String, but is not the String. In other words, a String can be input and/or output but is not the date-time object itself.
So your question, “How do I convert this String to a Date object without changing this format” makes no sense.
To generate a String in formats other than ISO 8601, convert your Instant to an OffsetDateTime or ZonedDateTime object, and use the DateTimeFormatter class. Search Stack Overflow for DateTimeFormatter to see more discussion and many examples.
Conversion
You should avoid the old java.util.Date class whenever possible. But if you must interface with old code not yet updated to the java.time types, you may convert to/from java.time via new methods added to the old date-time classes.
java.util.Date utilDate = java.util.Date.from( instant );
…and going the other direction…
Instant instant = utilDate.toInstant();
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

Categories