Форматирование строки даты/целого числа из общих настроек

Я не знаю, что я делаю неправильно? Но я пытаюсь отформатировать мою dateDue строку из SharedPreferences в формат MM/dd/yyyy из MMddyyyy.

Но мой код ниже возвращает все даты с косой чертой, но отображает дату 31.12.1969, а не мой номер SharedPreferences, который должен отображать 30.12.2022. Почему это должно вернуться так далеко? Это как-то связано с календарем?

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));
} 
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
73
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Давайте пройдемся по тому, что происходит, это довольно забавно, если вы знаете Java.

format.format(dateDue) реализован DateFormat.format(Object) (поскольку SimpleDateFormat расширяет DateFormat и наследует format(Object) и не переопределяет его). Код для этого:

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

obj в данном случае это целое число, поэтому оно вызывает format(new Date(obj)...

new Date(<some integer>) создает дату в <some integer> миллисекундах от 1 января 1970 года. https://docs.oracle.com/javase/8/docs/api/java/util/Date.html#Date-long-

А <some integer> здесь 12302022, или 12,3 миллиона миллисекунд, или 12 300 секунд, или 3,4 часа после полуночи 1 января 1970 года, а затем с разницей часовых поясов получается 31 декабря 1969 года.

Итак, как мне реализовать это в моем коде, чтобы он работал, потому что я вроде как понимаю, о чем вы говорите?

user20791491 25.12.2022 08:33

Начните с использования String.valueOf(dateDue), чтобы вы работали со строкой, а не с целым числом.

Mike Kim 25.12.2022 08:42

Я изменил все это на строки, и это дает мне эту ошибку: java.lang.IllegalArgumentException: невозможно отформатировать данный объект как дату

user20791491 25.12.2022 09: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 25.12.2022 09:20

тл;др

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

Подробности

Ответ Майка Кима кажется правильным и довольно умным в обнаружении проблемы, поскольку ваш вопрос четко не сформулирован. Этот ответ определил, что ваш вклад должен быть "12302022".

Java.время

Кроме того, вы должны знать, что используете ужасные классы даты и времени, которые много лет назад были вытеснены современными классами java.time, определенными в JSR 310.

Чтобы проанализировать ввод 12302022 в формате ММДДГГГГ, определите соответствующий шаблон форматирования.

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

LocalDate

Используйте это, чтобы преобразовать строку в объект LocalDate.

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

ld.toString() = 2022-12-30

ИСО 8601

Этот вывод LocalDate.toString находится в стандартном формате ISO 8601.

Совет. Используйте форматы ISO 8601 для текстового хранения и обмена значениями даты и времени. Форматы разработаны так, чтобы их можно было легко анализировать машиной, а также легко читать людьми.

Классы java.time по умолчанию используют форматы ISO 8601 при разборе/генерации текста.

Андроид

Android 26+ поставляется с реализацией классов java.time.

В более ранних версиях Android используйте новейшие инструменты для доступа к большинству функций java.time через «дешугаринг API».

Это прекрасно работает, но я хочу использовать косые черты вместо тире, и вы не можете изменить формат даты независимо от того, какой шаблон вы вставили.

user20791491 25.12.2022 10:03

Отображает ггггММдд

user20791491 25.12.2022 10:06

@user20791491 Определите еще один DateTimeFormatter, передайте LocalDate#format. Найдите Stack Overflow, чтобы узнать больше. Генерация текста из java.time уже обсуждалась много раз.

Basil Bourque 25.12.2022 18:01
Ответ принят как подходящий

Java.время

java.util API даты и времени и их API форматирования, SimpleDateFormat устарели и подвержены ошибкам. Рекомендуется полностью отказаться от их использования и перейти на современный Date-Time API.

Существующие ответы верны, но отсутствуют часть решения, которую вы ищете. Что вам нужно:

  1. Разберите строку даты в формате MMddyyyy.
  2. Отформатируйте проанализированную дату в строку формата MM/dd/yyyy.

Решение с использованием 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);
    }
}

Выход:

12/30/2022

Здесь вы можете использовать y вместо u, но я предпочитаюuy.

Узнайте больше о современном API Date-Time из Trail: Date Time.

Другие вопросы по теме