开发者

How to Format ISO-8601 in Java

I am trying to change from standard ISO 8601 format 2014-09-11T21:28:29.429209Z into a nice MMM d yyyy hh:mm z format, however my current code is failing.

public void setCreatedAt( String dateTime ) {

    LocalDate newDateTime = LocalDate.parse(dateTime);

    try {
        DateTimeFormatter for开发者_C百科mat = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a z");
        createdAt = newDateTime.format(format); 
    }
    catch (Exception e) {
    }

}

I am receiving the time and date from an api.


A java.time.LocalDate is "a date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03" so there is not enough information there. Use java.time.ZonedDateTime instead.

Also, swallowing exceptions like that makes it much harder to troubleshoot. When you don't intend to handle an exception either don't catch it at all, catch and re-throw it wrapped in a RuntimeException or at the very least log it (e.printStackTrace() or similar) .


tl;dr

Instant.parse( "2014-09-11T21:28:29.429209Z" )
       .atZone( ZoneId.of( "Asia/Kolkata" ) )
       .format( DateTimeFormatter.ofPattern("MMM d uuuu hh:mm a z" , Locale.US ) )

See this code run live at IdeOne.com.

Details

The Answer by Jakber will work technically but is misleading.

ZonedDateTime is for time zones

A ZonedDateTime is meant to have an assigned time zone such as America/Montreal or Pacific/Auckland.

But this input string lacks a time zone. The Z on the end is short for Zulu and means UTC, or in other words, an offset-from-UTC of zero hours, +00:00.

A time zone is a historical collection of offsets for a particular region with rules for upcoming changes to the offset for anomalies such as Daylight Saving Time (DST).

Instant

The input string is better parsed as an Instant which represents a moment on the timeline always in UTC. This class directly parses such strings in that particular standard ISO 8601 format, so no need for formatting pattern.

Instant instant = Instant.parse( "2014-09-11T21:28:29.429209Z" );

Adjust into time zone

You can adjust into a time zone to get a ZonedDateTime.

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z );

Generating string

To generate a string in the same format as input, simply call Instant::toString().

String output = instant.toString() ;

For your custom format using the wall-clock time of a region, use DateTimeFormatter with your custom formatting pattern. And your ZonedDateTime. As a good habit, always specify the desired Locale used for the human language in translation and cultural norms in formatting.

DateTimeFormatter f = DateTimeFormatter.ofPattern("MMM d uuuu hh:mm a z" , Locale.US );
String output = zdt.format( f ); 

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, and later
    • Built-in.
    • 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.


public void setCreatedAt(String dateTime) {
    SimpleDateFormat sdfSource = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
    SimpleDateFormat sdfTarget = new SimpleDateFormat("MMM d yyyy hh:mm a z", Locale.getDefault());
    try {
        Date date = sdfSource.parse(dateTime);
        String createdAt = sdfTarget.format(date);
        Log.e(TAG, "setCreatedAt: createdAt " + createdAt);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜