Generic Support for Iso 8601 Format in Java 6

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 DateTimeFormatters, 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



Leave a reply



Submit