Convert time strings to ISO 8601 format

I am trying to create a string in the format 2015-08-20T08: 26: 21.000Z
until 2015-08-20T08: 26: 21Z

I know that this can be done using some line-splitting methods, but I'm wondering if there is an elegant solution for this (with minimal code changes).

Both of the time lines above, the last one I need is Date in ISO 8601. http://tools.ietf.org/html/rfc3339#section-5.6

I tried several similar questions, such as converting a date string to milliseconds in java , but they actually do not solve the goal.

Also tried using:

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ"); String nowAsString = df.format(new Date()); 

But it still does not do String to String conversions. Getting the following error:

23: 04: 13,829 WARN [RuntimeExceptionMapper] detected RuntimeException: {}: java.lang.IllegalArgumentException: it is not possible to format this object as a date

Is there any library anyone can offer?

Thanks.

+7
java string time
source share
3 answers

TL; DR

 Instant.parse( "2015-08-20T08:26:21.000Z" ) .toString() 

2015-08-20T08: 26: 21Z

Formatting Date and Time

If all you want to do is to exclude .000 , then use time-time objects to parse your input string value, and then generate a new string representation of that date and time value in a different format.

ISO 8601

By the way, if this is your goal, the name of the Questions does not make sense, since both lines mentioned in the first sentence are valid ISO 8601 formatted lines.

  • 2015-08-20T08:26:21.000Z
  • 2015-08-20T08:26:21Z

java.time

Java 8 and later have the new java.time package . These new classes replace the old java.util.Date/.Calendar and java.text.SimpleDateFormat classes. These old classes were confusing, troublesome, and erroneous.

Instant

If you want only the UTC time zone, you can use the Instant class. This class represents a point on the timeline without taking into account any specific time zone (mainly UTC).

DateTimeFormatter.ISO_INSTANT

Calling instances of toString generates a string representation of the date and time value using the DateTimeFormatter.ISO_INSTANT formatting instance. This formatter automatically dies relative to a fractional second. If the value is a whole second, no decimal places are generated (obviously what the Question wants). For a fractional second, digits are displayed in groups of 3, 6, or 9, if necessary, to represent the value before nanosecond resolution. Note: this format may exceed the ISO 8601 limit in milliseconds (3 decimal places).

Code example

Here is sample code in Java 8 Update 51.

 String output = Instant.parse( "2015-08-20T08:26:21.000Z" ).toString( ); System.out.println("output: " + output ); 

: 2015-08-20T08: 26: 21Z

Transition to a fractional second .08

 String output = Instant.parse( "2015-08-20T08:26:21.08Z" ).toString( ); 

: 2015-08-20T08: 26: 21.080Z

If you are interested in any time zone other than UTC, then create a ZonedDateTime object from this Instant .

 ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , ZoneId.of( "America/Montreal" ) ) ; 
+9
source share

Your format is simply wrong, try the following: -

 try { String s = "2015-08-20T08:26:21.000Z"; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX"); Date d = df.parse(s); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); System.out.println(sdf.format(d)); } catch (ParseException e) { e.printStackTrace(); } 
+2
source share

Converting a String date of unknown formatting to a String date that uses known formatting can be done using two DateFormat objects β€” one dynamically configured to parse String input format, and one configured to generate formatted String output. For your situation, the formatting of the String input is not specified and must be provided by the caller, however the output formatting of the String can be configured to use ISO 8601 formatting without additional input. Essentially, generating a formatted String date in ISO 8601 format requires two inputs provided by the caller β€” a String containing the formatted date, and another String that contains the SimpleDateFormat format.

Here is the conversion described as Java code (I deliberately missed the null checks and checks, add them according to your code):

 private String formatDateAsIso8601(final String inputDateAsString, final String inputStringFormat) throws ParseException { final DateFormat iso8601DateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.ENGLISH); iso8601DateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); final DateFormat inputDateFormatter = new SimpleDateFormat(inputStringFormat, Locale.ENGLISH); final Date inputDate = inputDateFormatter.parse(inputDateAsString); return iso8601DateFormatter.format(inputDate); } 

If you want to change this method, please note that SimpleDateFormat not thread safe and you should not use it from a static context without a workaround for multi-threaded code ( ThreadLocal is usually used just such a workaround for SimpleDateFormat ).

An additional β€œgotcha” is to use Locale during the construction of SimpleDateFormat objects - do not delete the Locale configuration. It is not safe to allow the system to select Locale by default, as this depends on the user and the machine. If you allow Locale be used by default, you run the risk of getting temporary errors because your development machine uses a Locale different from your end-user Locale . You do not need to use my chosen language ENGLISH Locale , use another language perfectly (you should understand the rules of this Locale and, if necessary, modify the code). However, the no Locale specification and default system usage are incorrect and are likely to lead to many frustrating hours trying to diagnose an elusive error.

Please understand that this solution is not ideal compared to Java 8 and the inclusion of JodaTime classes such as Instant . I decided to answer using an outdated API, because that was what it seemed to you in your question. If you are using Java 8, I highly recommend learning and using the new classes as they improve in almost every possible way.

+2
source share

All Articles