Как преобразовать дату из базы данных в форматированную строку при возврате списка

#android #sqlite #string-formatting #android-room #date

#Android #sqlite #форматирование строк #android-комната #Дата

Вопрос:

Есть ли способ отформатировать дату в базе данных, пока она возвращается в списке? В настоящее время у меня есть база данных, которая содержит EntityScore. Он включает дату. Когда я запрашиваю базу данных для возврата определенного списка, я хочу получить дату в виде форматированной строки.

Доступ к базе данных:

 val list: ArrayList<List<ScoresReport>> = arrayListOf()

for(i in 0 until listHeadings.size)
    list.add(databasePersons.daoScores().getScoresDayPI(listHeadings[i].ID))
 

daoScores:

 @Query("SELECT date as text, AVG(score) as score FROM ScoresTable WHERE personID =:personID")
    fun getScoresDayPI(personID: Int) : List<ScoresReport>
 

Отчет о результатах:

 class ScoresReport(var text: String, var score: Int)
{}
 

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

Это то, что я хочу:

 @Query("SELECT date as SimpleDateFormat(pattern).format(date) -> text, AVG(score) as score FROM ScoresTable WHERE personID =:personID")
    fun getScoresDayPI(personID: Int) : List<ScoresReport>
 

Ответ №1:

Для этого вам нужно использовать a TypeConverter , как описано в этом посте Криса Бэйнса (я только что преобразовал его в Kotlin)

 object DateConverter {
    @TypeConverter
    @JvmStatic
    fun fromMillisToDate(millis: Long?): Date? {
        return millis?.let {
            return Date(millis)
        }
    }

    @TypeConverter
    @JvmStatic
    fun fromDateToMillis(date: Date?): Long? {
        return date?.time
    }
}
 

А затем вам нужно зарегистрировать это в вашем Room экземпляре базы данных с помощью TypeConverters аннотации, чтобы оно применялось ко всем вашим Date объектам в базе данных.

 @Database(
    entities = [
        User::class,
        Todo::class,
    ],
    version = 1
)
@TypeConverters(value = [DateConverter::class])
abstract class AppDatabase : RoomDatabase() {

    abstract fun userDao(): UserDao

    abstract fun todoDao(): TodoDao
}
 

Помните, что использование Date для хранения дат или временных меток является плохой
практикой, если вам нужно учитывать часовые пояса. Если вы в этом случае
, лучше, если вы используете OffsetDateTime объекты, и в сообщении Криса есть все
необходимые шаги

Комментарии:

1. У меня уже есть TypeConverter, который преобразует дату в long и наоборот. Что мне нужно, так это способ форматирования даты в строку «на лету».

Ответ №2:

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

Попробуйте изменить его на это:

 @Query("SELECT strftime('%d-%m-%Y %H:%M:%S', date) as scoredate, AVG(score) as score FROM ScoresTable 
WHERE personID =:personID")
 

Или попробуйте:

 @Query("SELECT strftime('%d-%m-%Y %H:%M:%S', date, unixepoch) as scoredate, AVG(score) as score FROM ScoresTable 
WHERE personID =:personID")
 

https://www.sqlite.org/lang_datefunc.html

Комментарии:

1. Кажется, это можно использовать в качестве решения, но по какой-то причине я получаю странный результат: ВЫБЕРИТЕ strftime(‘%m-%d-%Y’, дата), поскольку текст возвращает «11-24—471», когда он должен быть «04-14-2019». Может ли это иметь какое-то отношение к моим преобразователям типов?

2. Это странно. Я проверил параметры формата даты, и они выглядят как правильный синтаксис в соответствии с этой страницей: techonthenet.com/sqlite/functions/strftime.php Знаете ли вы, какая версия SQLite у вас есть? И будут ли в вашей системе какие-либо альтернативные настройки даты / времени?

3. Я думаю, это может быть потому, что мой TypeConverter преобразует дату в long, поэтому, когда он извлекает дату, он фактически извлекает long, а затем пытается отформатировать его, когда формат должен быть строкой. Есть предложения?

4. Определяется ли столбец SQLite как ТЕКСТОВЫЙ или целочисленный? Ознакомьтесь с этой ссылкой: sqlite.org/lang_datefunc.html в нем упоминается модификатор unixepoch, который используется для интерпретации дат, хранящихся в виде целых чисел. Не уверен, что произойдет, если вы сохраните целочисленную дату в текстовом столбце.