How to Format ISO-8601 in Java

前端 未结 3 828
北海茫月
北海茫月 2020-12-04 00:00

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.

相关标签:
3条回答
  • 2020-12-04 00:09

    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.

    0 讨论(0)
  • 2020-12-04 00:14

    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) .

    0 讨论(0)
  • 2020-12-04 00:21
    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 讨论(0)
提交回复
热议问题