How can I convert String to timestamp with timezone? - java

In my Spring Boot project, I have this array of objects (List<Object> values)
["2021-06-13T08:50:04.707Z", 3197691, 1933]
The first element is a String and represents a timestamp with timezone.
I can get the first element like this:
String time = (String) values.get(0);
How can I convert it in date or time format in order to insert in a PostgreSQL table?

The given timestamp string conforms to the ISO 8601 standards.
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.
Demo:
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.parse("2021-06-13T08:50:04.707Z");
System.out.println(odt);
}
}
Output:
2021-06-13T08:50:04.707Z
Check this answer to learn how to use OffsetDateTime with JDBC.
Learn more about the modern Date-Time API from Trail: Date Time.
* 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.

First thing you must understand the timestamp format, and for your timestamp format is
yyyy-MM-dd'T'hh:mm:ss.SSS'Z'
Don't forget to add 'T' and 'Z'
Then, to convert from string date to Date class you can use SimpleDateFormat class
String dateInString = "2021-06-13T08:50:04.707Z";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
Date date = dateFormat.parse(dateInString);
Then use the data object to insert to your query. Or if you are using JPA, simply just create the entity and put data object to the variable.

Related

Date to string parsing [duplicate]

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.
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().
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" ) ;
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?
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
Not sure about the Java parsing, but that's ISO8601: http://en.wikipedia.org/wiki/ISO_8601
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");
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.
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
In JavaScript
let isoDateTimeString = new Date().toISOString();
Description
Date/time format like "YYYY-MM-DDThh:mm:ss.SSSZ" is ISO 8601 date/time format.
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());
}
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);
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)
#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.

ISO 8601 date format string to Date object in Java

I tried searching answer for different formats of ISO 8601 date only but not able to identify answer or material which contains these details
I am trying to receive ISO 8601 date format(date only as its date of birth) string and convert it into date object and later persist in dB. Is yyyy-MM-dd only date format that is considered as ISO 8601 date format. If so I can handle this accordingly but is there multiple date ISO 8601 date formats, if so can you please guide what is the best way to parse given string and convert to date object in Java
Yes, yyyy-MM-dd is the ISO 8601 format for a date without time of day and without time zone.
To store into an SQL database using either a JDBC 4.2 or later driver or a modern JPA implementation such as Hibernate 5, you have got nothing to use a Date object for (no matter if you meant java.util.Date or java.sql.Date). I recommend that instead you use java.time, the modern Java date and time API. The class to use for a date without time of day is LocalDate. And you can store one into your database without any conversion.
LocalDate parses ISO 8601 format as its default, that is, without any explicit formatter:
String receivedString = "1962-11-27";
LocalDate dateOfBirth = LocalDate.parse(receivedString);
System.out.println("Date of birth is " + dateOfBirth);
LocalDate also gives ISO 8601 format back when we print it:
Date of birth is 1962-11-27
I haven’t given you the full story yet, though. yyyy-MM-dd is the extended format that is by far most often used. There is also a basic format that is compacter in that it leaves out the hyphens: yyyyMMdd. I suggest that you insist on getting your date string in the extended format. If you cannot do that, you will have to specify a formatter for parsing:
String receivedString = "19621127";
LocalDate dateOfBirth = LocalDate.parse(
receivedString, DateTimeFormatter.BASIC_ISO_DATE);
This will give you a LocalDate equal to and indistinguishable from the one we had before.
To save into your database using JDBC:
PreparedStatement pStmt
= yourDatabaseConnection.prepareStatement(
"insert into your_table (date_of_birth) values (?);");
pStmt.setObject(1, dateOfBirth);
int insertedRows = pStmt.executeUpdate();
Note the use of setObject(), not setDate().
Links
Wikipedia article: ISO 8601
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Related question: Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2

java format particular date with T character

What is the correct form for parse this date?: 2015-05-29T00:00:00+02:00
DateFormat format = new SimpleDateFormat("yyyyy-mm-dd hh:mm:ss");
Date data = format.parse(dataValue);
Try with
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Notice that
MM represents months, while mm represents minutes.
if you want to have 24h format use HH, hh is for 12h format
XXX represents time zone in format like -08:00
to add literal like T in format you need to surround it with single quotes ' like 'T'
java.time
The legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Since the modern date-time API is based on ISO 8601 standards, you are not required to use a DateTimeFormatter object explicitly to parse a date-time string conforming to the ISO 8601 standards. Your date-time string contains timezone offset string (+02:00) and therefore, the most appropriate type to be used to parse it is OffsetDateTime.
Demo:
import java.time.OffsetDateTime;
public class Main {
public static void main(String args[]) {
OffsetDateTime odt = OffsetDateTime.parse("2015-05-29T00:00:00+02:00");
System.out.println(odt);
}
}
Output:
2015-05-29T00:00+02:00
For whatsoever reason, if you need an instance of java.util.Date from this object of OffsetDateTime, you can do so as follows:
Date date = Date.from(odt.toInstant());
Learn more about the the modern date-time API* from Trail: Date Time.
* 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.

Unparsable Date with colon-separated timezone

I'm trying to parse this String
2014-04-04T14:28:38+02:00
It should be ISO 8601 format. But i can't parse it to a correct Date.
I've tried the following:
String example = "2014-04-04T14:28:38+02:00"
public final static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz")
Date tempDate = df.parse(example)
But I get always the message "unparseable Date"
I can not change the example because it's a value from a webservice.
Could it be there is a probleme with "+02:00" instead of "+0200" ?
Thanks a lot
java.time
The modern date-time API is based on ISO 8601 and thus, you do not need to use a parser (e.g. DateTimeFormatter) explicitly in order to parse the given date-time string as it is already in ISO 8601 format.
Demo:
import java.time.OffsetDateTime;
import java.util.Date;
public class Main {
public static void main(String args[]) {
OffsetDateTime odt = OffsetDateTime.parse("2014-04-04T14:28:38+02:00");
System.out.println(odt);
// In case you need java.util.Date
Date date = Date.from(odt.toInstant());
// ...
}
}
Output:
2014-04-04T14:28:38+02:00
Learn more about the the modern date-time API* from Trail: Date Time.
* 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.
Starting from Java7, to handle +02:00, you can use the following format:
"yyyy-MM-dd'T'hh:mm:ssXXX"
This can be seen in the SimpleDateFormat documentation
The ISO8601 date format can be most easily parsed using Joda Time which can be use as a library.
It seems that a form of Joda Time got into Java 8 as JSR310 but I have not worked with it.

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.
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().
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" ) ;
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?
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
Not sure about the Java parsing, but that's ISO8601: http://en.wikipedia.org/wiki/ISO_8601
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");
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.
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
In JavaScript
let isoDateTimeString = new Date().toISOString();
Description
Date/time format like "YYYY-MM-DDThh:mm:ss.SSSZ" is ISO 8601 date/time format.
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());
}
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);
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)
#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.

Categories

Resources