-2

I am trying to get the right date to display but no matter what I do, or the date, it changes the month to January. What am I doing wrong?

  private static String formatDate(String dateFormat) {
    String jsonDate = "yyyy-mm-dd'T'HH:mm:ss'Z'";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(jsonDate, Locale.getDefault());
    try {
        Date parsedDate = simpleDateFormat.parse(dateFormat);
        String parsedDatePattern = "MM dd y";
        SimpleDateFormat formatJsonDate = new SimpleDateFormat(parsedDatePattern, Locale.getDefault());

        return formatJsonDate.format(parsedDate);
    } catch (ParseException e) {
        Log.e(LOG_TAG, "~*&~*&~*&Error parsing JSON date: ", e);
        return "";
    }
}
jstmeknz
  • 1
  • 1
  • 1

1 Answers1

3

tl;dr

Instant
.parse( "2018-01-23T01:23:45.123456789Z" )
.atZone( 
    ZoneId.of( "Africa/Tunis" )
)
.toLocalDate()
.format(
    DateTimeFormatter
    .ofLocalizedDate( FormatStyle.SHORT )
    .withLocale( Locale.US )
)

1/23/18

Case-sensitive

Formatting patterns are case-sensitive.

For month number, use all uppercase MM.

Another problem: Your formatting pattern unwisely ignores the Z on the end. That letter provides valuable information, indicating UTC, an offset of zero. Pronounced “Zulu”.

java.time

You are using terrible old classes that were supplanted years ago by the java.time classes.

Your input format is standard ISO 8601 format, used by default in the Instant class that replaced java.util.Date.

Instant instant = Instant.parse( "2018-01-23T01:23:45.123456789Z" ) ;

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
ZonedDateTime zdt = instant.atZone( z ) ;

Extract the date-only portion, as that is the focus of your Question.

LocalDate ld = zdt.toLocalDate() ;

Generate text representing that date in standard ISO 8601 format.

String output = ld.toString() ;

Automatically localize.

Locale l = Locale.US ;  // Or Locale.CANADA_FRENCH etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( l ) ;
String output ld.format( f ) ;

Or define your own formatting pattern as shown in many dozens, if not hundreds, of other Answers already posted. Search for DateTimeFormatter.ofPattern.


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?

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154