Java iso 8601 timestamp

Converting a time String to ISO 8601 format

I am trying to create a String in a format like 2015-08-20T08:26:21.000Z
to 2015-08-20T08:26:21Z I know it can be done with some String splitting techniques, but i am wondering if there is an elegant solution for that (with minimal code changes). Both of the above are time strings, the final one which i need is Date in ISO 8601 . https://www.rfc-editor.org/rfc/rfc3339#section-5.6 I have tried a few similar questions like converting a date string into milliseconds in java but they dont actually solve the purpose. 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 any String to String conversions. Getting the following error: 23:04:13,829 WARN [RuntimeExceptionMapper] caught RuntimeException: <>: java.lang.IllegalArgumentException: Cannot format given Object as a Date Is there some library which someone can suggest ? Thanks.

A DateFormat does String to Date and Date to String conversion. You want String to String conversion. You can thus use a DateFormat to do String to Date conversion, and another one doing Date To String conversion. And no, they don’t represent difference timezones. One has a millisecond part and the other doesn’t. That’s the only difference. The final Z means Zulu time, i.e. UTC timezone.

@CodeMonkey So your goal is to eliminate the .000 ? Your title is confusing as both date-time strings in your first sentence are valid ISO 8601 strings.

Читайте также:  Starttls command first php

3 Answers 3

tl;dr

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

Date-Time Formatter

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

ISO 8601

By the way, if that is your goal, the Question’s title make no sense as both strings mentioned in the first sentence are valid ISO 8601 formatted strings.

java.time

Java 8 and later has the new java.time package. These new classes supplant the old java.util.Date/.Calendar & java.text.SimpleDateFormat classes. Those old classes were confusing, troublesome, and flawed.

Instant

If all you want is UTC time zone, then you can use the Instant class. This class represents a point along the timeline without regard to any particular time zone (basically UTC).

DateTimeFormatter.ISO_INSTANT

Calling an Instant’s toString generates a String representation of the date-time value using a DateTimeFormatter.ISO_INSTANT formatter instance. This formatter is automatically flexible about the fractional second. If the value has a whole second, no decimal places are generated (apparently what the Question wants). For a fractional second, digits appear in groups of 3, 6, or 9, as needed to represent the value up to nanosecond resolution. Note: this format may exceed ISO 8601 limit of milliseconds (3 decimal places).

Example code

Here is some example code in Java 8 Update 51.

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

Changing to a fractional second, .08

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

If interested in any time zone other than UTC, then make a ZonedDateTime object from that Instant .

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

Your format is just not right try this :-

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)

Don’t use ‘Z’. Use X. The final Z means that this is a time is the UTC timezone. So the result is completely different. BTW, due to the presence of DST in your default timezone and the absence of DST in UTC, some Strings don’t represent any existing date in the local timezone, but do in UTC.

Conversion of a date String of unknown formatting into a date String that uses known formatting can be accomplished using two DateFormat objects- one dynamically configured to parse the format of the input String , and one configured to generate the formatted output String . For your situation the input String formatting is unspecified and must be provided by the caller, however, the output String formatting can be configured to use ISO 8601 formatting without additional input. Essentially, generating an ISO 8601 formatted date String output requires two inputs provided by the caller- a String containing the formatted date and another String that contains the SimpleDateFormat format.

Here is the described conversion as Java code (I deliberately have left out null checks and validations, add these as appropriate for your code):

private String formatDateAsIso8601(final String inputDateAsString, final String inputStringFormat) throws ParseException

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

An additional «gotcha» is the use of a Locale during the construction of the SimpleDateFormat objects- do not remove the Locale configuration. It is not safe to allow the system to choose to use the default Locale because that is user/machine specific. If you do allow it to use the default Locale , you run the risk of transient bugs because your development machine uses a Locale different than the Locale of your end-user. You do not have to use my selected ENGLISH Locale , it is perfectly fine to use a different Locale (you should understand the rules of that Locale and modify the code as appropriate however). Specification of no Locale and utilization of the system default is incorrect however, and likely will lead to many frustrating hours trying to diagnose an elusive bug.

Please understand this solution is not ideal as of Java 8 and the inclusion of the JodaTime based classes, like Instant . I chose to answer using the outdated API’s because those were what you seemed concerned with in your question. If you are using Java 8 I strongly urge to learn and utilize the new classes as they are an improvement in almost every conceivable way.

Источник

Convert java.util.Calendar ISO 8601 format to java.sql.Timestamp

I have a date in ISO 8601 date format 2015-09-08T01:55:28Z . I used this code to convert the ISO 8601 fate to a Calendar object:

Calendar cal = javax.xml.bind.DatatypeConverter.parseDateTime("2015-09-08T01:55:28Z"); 

and now I need to use the cal.getTime() to get my time, but I need to convert it to a java.sql.Timestamp . I tried to do this:

final Timestamp finalDate = (Timestamp) cal.getTime(); 
java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Timestamp 

2 Answers 2

As the exception says: Calendar::getTime() returns a java.util.Date object, not a java.sql.Timestamp object. So you cannot cast it to a Timestamp object.

Timestamp timestamp = new Timestamp(cal.getTimeInMillis()); 

And also consider to replace Calendar with the new Date & Time API introduced in Java SE 8.

java.time

The modern way in Java 8 and later is to use the new java.time framework. These new classes supplant the old java.util.Date/.Calendar that have proven to be confusing and troublesome.

An Instant is a moment on the timeline, a count of nanoseconds from first moment of 1970 in UTC. The class is able to parse strings such as yours that comply with the ISO 8601 format.

String input = "2015-09-08T01:55:28Z"; Instant instant = Instant.parse( input ); 

Database via old java.sql types

From an Instant, we can get a java.sql.Timestamp by calling the from method newly added to this old class.

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ); 

We could combine all three lines into a one-liner, not that I recommend it (makes debugging more difficult).

 java.sql.Timestamp ts = Timestamp.from( Instant.parse( "2015-09-08T01:55:28Z" ) ); 

Database via java.time types

As of JDBC 4.2, a compliant JDBC driver should be able to pass the java.time types via getObject and setObject on a PreparedStatement . If your driver does not, use the conversion methods for the old classes.

myPreparedStatement.setObject( 1 , instant ); 

Источник

convert string timestamp to ISO 8601 compliant string

I want to convert above timestamp into ISO 8601 compliant String, with milliseconds and timezone so it should look like this after conversion:

Fromwhere would you think you couldget the milliseconds? They aren’t even in the ISO-8601 string you say you want.

That -08:00 is an offset-from-UTC, not a time zone. A time zone is a history of the changes to a region’s offset. Ex: America/Montreal or Asia/Kolkata .

2 Answers 2

The newer java.time classes work so well with ISO 8601 strings.

 String dateTimeString = "01/14/2016 07:37:36PM"; String offsetString = "-08:00"; LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, DateTimeFormatter.ofPattern("MM/dd/uuuu hh:mm:ssa")); ZoneOffset offset = ZoneOffset.of(offsetString); String formattedTimestamp = dateTime.atOffset(offset).toString(); System.out.println(formattedTimestamp); 

Stay away from outdated classes like SimpleDateFormat .

What is offsetString is not present? I understand that in this case you want an offset of Z for UTC. For example like this:

 ZoneOffset offset; if (offsetString == null) < offset = ZoneOffset.UTC; >else < offset = ZoneOffset.of(offsetString); >String formattedTimestamp = dateTime.atOffset(offset).toString(); 

With a null offsetString we now get

The classes in java.time (of which I’m using but a few) are described in JSR-310 and come built-in with Java 8. What if you would like to use them with Java 6 or 7? You get the ThreeTen Backport (link below). It gives you the majority of the classes for Java 6 and 7. I’m not perfectly happy to tell you you need an external library, but in this case it’s only until you move to Java 8. I hope you will soon.

I am sure it can be done with JodaTime too, but I haven’t got experience with it, so cannot give you the details there. What I do know, I have read the the folks behind JodaTime now recommend you move over to java.time instead. So I am asking you to swap one external library for a newer (and supposedly better) one. In itself I’m not unhappy with that. Only if you already have a codebase that uses JodaTime, it’s not really trivial.

Источник

Оцените статью