1

I do not know what I am doing wrong? But what I am trying to do is format my dateDue String from SharedPreferences to the format of MM/dd/yyyy from MMddyyyy.

But my code below returns all dates with slashes but it displays the date 12/31/1969 and not my SharedPreferences number, which should display 12/30/2022. Why would it go back so far? Does it have to do with something with Calendar?

String myFormat = "MM/dd/yyyy";
SimpleDateFormat format = new SimpleDateFormat(myFormat);

SharedPreferences settings = context.getApplicationContext().getSharedPreferences(name, 0);
Integer dateDue = Integer.valueOf(settings.getInt("dateDue", 0));

format = new SimpleDateFormat(myFormat);
String date = format.format(dateDue);

if (Integer.valueOf(String.valueOf(dueAmount)) > 0) { 
    holder.getDateDue.setText(String.valueOf(date));
} 
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110

3 Answers3

3

tl;dr

LocalDate.parse( 
    "12302022" , 
    DateTimeFormatter.ofPattern( "MMdduuuu" ) 
) 

Details

The Answer by Mike Kim appears to be correct, and quite clever in detecting the problem as your Question is not clearly stated. That Answer determined your input must have been "12302022".

java.time

Additionally, you should know that you are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.

To parse your input 12302022 in MMDDYYYY format, define a formatting pattern to match.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMdduuuu" ) ;

LocalDate

Use that to parse the string into a LocalDate object.

LocalDate ld = LocalDate.parse( "12302022" , f ) ;

ld.toString() = 2022-12-30

ISO 8601

That output of LocalDate.toString is in standard ISO 8601 format.

Tip: Use ISO 8601 formats for storing and exchanging date-time values textually. The formats are designed to be easily parsed by machine as well as easily read by humans.

The java.time classes use ISO 8601 formats by default when parsing/generating text.

Android

Android 26+ comes with an implementation of the java.time classes.

In earlier Android, use the latest tooling to access most of the java.time functionality via “API desugaring”.

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

Let's walk through what is happening, it's kind of funny if you know Java.

format.format(dateDue) is implemented by DateFormat.format(Object) (because SimpleDateFormat extends DateFormat and inherits format(Object) and does not override it). The code for that is:

if (obj instanceof Date)
    return format( (Date)obj, toAppendTo, fieldPosition );
else if (obj instanceof Number)
    return format( new Date(((Number)obj)...

obj in this case is an Integer which is a Number, so it calls format(new Date(obj)...

new Date(<some integer>) creates a date that is <some integer> milliseconds from January 1, 1970. https://docs.oracle.com/javase/8/docs/api/java/util/Date.html#Date-long-

And <some integer> here is 12302022, or 12.3 million milliseconds or 12,300 seconds or 3.4 hours after January 1, 1970 at midnight, and then with the timezone difference you get 12/31/1969.

Mike Kim
  • 115
  • 6
  • So how would I implement this into my code to work, because I kind of understand of what your saying? – user20791491 Dec 25 '22 at 07:33
  • Start by using `String.valueOf(dateDue)` so you're working with a string instead of an integer. – Mike Kim Dec 25 '22 at 07:42
  • I changed it all to strings and it gives me this error: java.lang.IllegalArgumentException: Cannot format given Object as a Date – user20791491 Dec 25 '22 at 08:18
  • `String dateDue = settings.getString("dateDue", String.valueOf(0)); String dueDate = dateDue; if (Integer.valueOf(String.valueOf(dueAmount)) > 0) { holder.getDateDue.setText(format.format(dueDate)); }` – user20791491 Dec 25 '22 at 08:20
1

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API.

Existing answers are correct but missing the solution part you are looking for. What you need is:

  1. Parse the date string which is in the format, MMddyyyy.
  2. Format the parsed date into a string of format MM/dd/yyyy.

Solution using java.time API:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

class Main {
    public static void main(String[] args) {
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("MMdduuuu", Locale.ENGLISH);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/uuuu", Locale.ENGLISH);

        // Given below is a sample date string. In your case it may be,
        // String strDateDue settings.getString("dateDue", String.valueOf(0));
        String strDateDue = "12302022";

        LocalDate date = LocalDate.parse(strDateDue, parser);
        String formatted = date.format(formatter);
        System.out.println(formatted);
    }
}

Output:

12/30/2022

Here, you can use y instead of u but I prefer u to y.

Learn more about the modern Date-Time API from Trail: Date Time.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110