Generic support for ISO 8601 format in Java 6
Seems that you can use this:
import java.util.Calendar;
import javax.xml.bind.DatatypeConverter;
public class TestISO8601 {
public static void main(String[] args) {
parse("2012-10-01T19:30:00+02:00"); // UTC+2
parse("2012-10-01T19:30:00Z"); // UTC
parse("2012-10-01T19:30:00"); // Local
}
public static Date parse(final String str) {
Calendar c = DatatypeConverter.parseDateTime(str);
System.out.println(str + "\t" + (c.getTime().getTime()/1000));
return c.getTime();
}
}
How to format an ISO-8601 string in Java?
private String getZonedDateTime(String startTime,String inExpectedTimeZone){
return ZonedDateTime
.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"))
.withZoneSameInstant(ZoneId.of(inExpectedTimeZone)).format(DateTimeFormatter.ofPattern("hh:mm a"));
}
In the above method just pass the zulu string and expected Time in which you want the value it will be parsed using java 8 ZonedDateTime and DateTimeFormatter.
Which type of date format it is?? 2018-09-06T10:12:21-0300
What type of date format is it?
This format is one of the ISO 8601 standard, but obviously not for the java.time.format.DateTimeFormatter
which considers it a custom format consisting of ISO-standard date and time of day plus an offset from UTC without a separator (colon) between hours and minutes.
And how can I format it to something like that "06 Sep"
???
You need to define two DateTimeFormatter
s, one for parsing the non-standard input and the other one for outputting day of month and abbreviated month name only. Here's an example:
fun main(args: Array<String>) {
// some non-ISO formatted String
val inputDateTime = "2018-09-06T10:12:21-0300"
// build up a DateTimeFormatter that can parse such a String
val inputParser = DateTimeFormatterBuilder()
// date part uuuu-MM-dd
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T') // the T separating date from time
// the time of day part
.append(DateTimeFormatter.ISO_LOCAL_TIME)
// the offset part without a separator between hours and minutes
.appendPattern("X")
// (just for completeness) a locale
.toFormatter(Locale.ENGLISH)
// parse the String to an OffsetDateTime
val offsetDateTime = OffsetDateTime.parse(inputDateTime, inputParser)
// define another formatter for output, make it only use day of month and abbreviated month in English
val outputFormatter = DateTimeFormatter.ofPattern("dd MMM", Locale.ENGLISH)
// print the results
println("$offsetDateTime ---> ${offsetDateTime.format(outputFormatter)}")
}
Example output:
2018-09-06T10:12:21-03:00 ---> 06 Sep
DateTime with Timezone to another format
ThreeTenABP
Since you’ve got a working solution using java.time and since SimpleDateFormat
is causing trouble (not only for you: it is notoriously troublesome), I suggest that you use the backport of java.time. It has been adapted to Android in the ThreeTenABP project. See the links at the bottom.
Strictly speaking only the central and most used parts of java.time have been backported. However, that covers all that is used in at least 99 % of programs that use java.time, and I am sure that the solution that you have will work unchanged on the backport too. When I say unchanged, one change is necessary: you must import the date and time classes from org.threeten.bp
with subpackages.
In case you do insist on doing without the backport I also include links to questions about parsing ISO 8601 format. ISO 8601 is an international standard and this is the format you have got. Be aware, however: There is no way whatsoever that SimpleDateFormat
can correctly parse 6 decimals on the seconds. It supports only milliseconds, exactly three decimals (not 2, not 4, not 6).
Links
- 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.
- Wikipedia article: ISO 8601
- Similar question: Converting ISO 8601-compliant String to java.util.Date
- Similar question: Java : Cannot format given Object as a Date
- Similar question: Generic support for ISO 8601 format in Java 6
- Similar question: Parsing ISO-8601 DateTime in java
- Similar Android question: Parsing ISO-8601 DateTime in java
- Similar question: How to parse “yyyy-MM-dd'T'HH:mm:ss.SSSXXX” date format to simple in Android?
- Similar question: Not able to convert the string to date on Android
Validating ISO 8601 Duration string with fractions
Assuming the fractional part can only appear if there are no more digits to the right, you can use
^P(?!.*\d[,.]\d.*\d)(?!$)(\d+(?:[,.]\d+)?Y)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?W)?(\d+(?:[,.]\d+)?D)?(T(?=\d)(\d+(?:[,.]\d+)?H)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?S)?)?$
See the regex demo.
The (?!.*\d[,.]\d.*\d)
negative lookahead fails the match if there is a number with a fractional part followed with another number anywhere in the string.
You can learn more about the pattern used here in the Regex for ISO 8601 durations post.
2021-04-05T16:25:45.000+00:00 Time stamp change in SimpleDateFormat(yyyy-MM-dd hh:mm:ss a)
java.time through desugaring
Consider using java.time, the modern Java date and time API, for your date and time work. Use for example this output formatter:
private static final DateTimeFormatter OUTPUT_FORMATTER
= DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss a", Locale.forLanguageTag("en-IN"));
With it do:
String date = "2021-04-05T16:25:45.000+00:00";
OffsetDateTime dateTime = OffsetDateTime.parse(date);
String formattedDate = dateTime.format(OUTPUT_FORMATTER);
System.out.println(formattedDate);
Output:
2021-04-05 04:25:45 PM
You may use a different locale for the output formatter as appropriate for your requirements. The choice of locale determines which strings are used for AM and PM.
I am exploiting the fact that the string that you have got is in ISO 8601 format. offsetDateTime
parses this format as its default, that is, without any explicit formatter.
What went wrong in your code?
You tried using a format pattern string of yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
for a date string of 2021-04-05T16:25:45.000+00:00
. The 'Z'
in single quotes in the format pattern string means that your date string must end in a literal Z
. When instead it ended in +00:00
, parsing failed with a ParseException
. If you didn’t see the output from e.printStackTrace();
in your code, you have got a serious flaw in your project setup that you should fix before worrying about how to parse the date string. In any case, since parsing failed, parsedDate
kept its initial value of null
, which caused outputFormat.format(parsedDate)
to throw the NullPointerException
that you did see.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links
- 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). - Java 8+ APIs available through desugaring
- ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
- Wikipedia article: ISO 8601
How to get ISO format from time in milliseconds in Java?
I thought you had asked how to get the time in this format "yyyy-MM-dd HH:mm:ss,SSS"
One way is to use java's SimpleDateFormat:
http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
NOTE that this is not thread-safe.
...
Date d = new Date(1344855183166L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
String dateStr = sdf.format(d);
...
Convert Date from ISO 8601 Zulu string to java.time.Instant in Java 8
tl;dr
convert string date format into java.time.Instant
Skip the formatting pattern. Just parse.
Instant.parse( "2018-07-17T09:59:51.312Z" )
ISO 8601
Yes, you used incorrect formatting pattern as indicated in the first Answer.
But you needn't specify a formatting pattern at all. Your input string is in standard ISO 8601 format. The java.time classes use ISO 8601 formats by default when parsing/generating strings.
The Z
on the end means UTC, and is pronounced “Zulu”.
Instant instant = Instant.parse( "2018-07-17T09:59:51.312Z" ) ;
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
- 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.
String of ISO-8601 datetime to number of seconds in Java
try this way
String DateStr="2012-05-31T13:48:04Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Date d=sdf.parse(DateStr);
System.out.println(d.getTime());
output 1338452284000
From the comments of OP
getTime() returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.Source
Related Topics
Messagebodyprovidernotfoundexception While Running Jar from Command Line
What Are Shadow Variables in Java
Files.Walk(), Calculate Total Size
Differences Between Just in Time Compilation and on Stack Replacement
A Confusion About Java String Literal Pool and String's Concatenation
Display Mouse Coordinates Near Mouse as Hints on Mouse Move
Java: Exceptions as Control Flow
Java: Import Statement VS Fully Qualified Name
Using Bufferedreader.Readline() in a While Loop Properly
Java Gif Animation Not Repainting Correctly
Minimum Spring Version Compatible with Java 11
How to Find Out If the Value Contained in a String Is Double or Not
Is Asynchronous Jdbc Call Possible
Comparing Date Strings in Java
Can a Spring Boot @Restcontroller Be Enabled/Disabled Using Properties