У меня возникли проблемы при работе с датами в моем приложении Android, которое использует SQLite. У меня есть пара вопросов:
- Какой тип я должен использовать для хранения дат в SQLite (текст, целое число, ...)?
- Учитывая лучший способ хранить даты, как правильно хранить его, используя ContentValues?
- Каков наилучший способ получить дату из базы данных SQLite?
- Как сделать выбор SQL на SQLite, упорядочив результаты по дате?
Ответы:
Вы можете использовать текстовое поле для хранения дат внутри
SQLite
.Сохранение даты в формате UTC, по умолчанию, если вы используете
datetime('now')
(yyyy-MM-dd HH:mm:ss)
, разрешит сортировку по столбцу даты.Получив даты в виде строк,
SQLite
вы можете затем отформатировать / преобразовать их, как требуется, в локальные региональные форматы, используя Календарь илиandroid.text.format.DateUtils.formatDateTime
метод.Вот метод локализованного форматирования, который я использую;
источник
Лучший способ - сохранить даты в виде числа, полученного с помощью команды Календарь.
Зачем это делать? Прежде всего, получить значения из диапазона дат очень просто. Просто преобразуйте свою дату в миллисекунды, а затем сделайте соответствующий запрос. Сортировка по дате также проста. Призывы к конвертации между различными форматами также легки, как я включил. Суть в том, что с помощью этого метода вы можете делать все, что вам нужно, без проблем. Будет немного трудно прочитать необработанное значение, но это более чем компенсирует этот небольшой недостаток, заключающийся в том, что он легко читается машиной и может использоваться. И на самом деле, относительно легко создать ридер (и я знаю, что есть некоторые), который автоматически конвертирует метку времени в дату как таковую для удобства чтения.
Стоит отметить, что значения, которые из этого получаются, должны быть длинными, а не int. Целое число в sqlite может означать много вещей, от 1 до 8 байтов, но почти для всех дат работает 64-битная или длинная строка.
РЕДАКТИРОВАТЬ: Как было отмечено в комментариях, вы должны использовать,
cursor.getLong()
чтобы правильно получить метку времени, если вы делаете это.источник
Для хранения вы можете использовать служебный метод
вот так:
Другой полезный метод заботится о загрузке
можно использовать так:
Упорядочивание по дате - это простое предложение SQL ORDER (потому что у нас есть числовой столбец). Следующее упорядочит по убыванию (то есть самая новая дата идет первой):
Всегда убедитесь , чтобы сохранить время UTC / GMT , особенно при работе с
java.util.Calendar
иjava.text.SimpleDateFormat
что использовать по умолчанию (то есть ваше устройство) часовой пояс.java.util.Date.Date()
безопасно использовать, так как это создает значение UTC.источник
SQLite может использовать текстовые, реальные или целочисленные типы данных для хранения дат. Более того, всякий раз, когда вы выполняете запрос, результаты отображаются в формате
%Y-%m-%d %H:%M:%S
.Теперь, если вы вставляете / обновляете значения даты / времени, используя функции даты / времени SQLite, вы также можете хранить миллисекунды. Если это так, результаты отображаются в формате
%Y-%m-%d %H:%M:%f
. Например:Теперь выполним несколько запросов, чтобы проверить, действительно ли мы можем сравнивать время:
Вы можете проверить то же самое ,
SELECT
используяcol2
иcol3
и вы получите те же результаты. Как видите, второй ряд (126 миллисекунд) не возвращается.Обратите внимание, что
BETWEEN
это включено, поэтому ...... вернет тот же набор.
Попробуйте поиграть с разными диапазонами даты и времени, и все будет работать так, как ожидается.
Как насчет без
strftime
функции?Как насчет без
strftime
функции и без миллисекунд?Как насчет
ORDER BY
?Работает просто отлично.
Наконец, когда речь идет о реальных операциях внутри программы (без использования исполняемого файла sqlite ...)
Кстати: я использую JDBC (не уверен насчет других языков) ... драйвер sqlite-jdbc v3.7.2 от xerial - возможно, более новые версии меняют поведение, описанное ниже ... Если вы разрабатываете в Android, вы не делаете нужен jdbc-драйвер. Все операции SQL могут быть отправлены с использованием
SQLiteOpenHelper
.JDBC имеет различные методы , чтобы получить фактические значения даты / времени из базы данных:
java.sql.Date
,java.sql.Time
, иjava.sql.Timestamp
.Соответствующие методы в
java.sql.ResultSet
(очевидно)getDate(..)
,getTime(..)
иgetTimestamp()
соответственно.Например:
Поскольку SQLite не имеет фактического типа данных DATE / TIME / TIMESTAMP, все эти 3 метода возвращают значения, как если бы объекты были инициализированы с 0:
Итак, вопрос заключается в следующем: как мы можем на самом деле выбирать, вставлять или обновлять объекты Date / Time / Timestamp? Там нет простого ответа. Вы можете попробовать разные комбинации, но они заставят вас встроить функции SQLite во все операторы SQL. Намного проще определить служебный класс для преобразования текста в объекты Date внутри вашей Java-программы. Но всегда помните, что SQLite преобразует любое значение даты в UTC + 0000.
Таким образом, несмотря на общее правило всегда использовать правильный тип данных или даже целые числа, обозначающие время Unix (миллисекунды с начала эпохи), я считаю, что гораздо проще использовать формат SQLite по умолчанию (
'%Y-%m-%d %H:%M:%f'
или в Java'yyyy-MM-dd HH:mm:ss.SSS'
), а не усложнять все ваши операторы SQL с помощью SQLite функции. Первый подход гораздо проще поддерживать.TODO: Я проверю результаты при использовании getDate / getTime / getTimestamp внутри Android (API15 или лучше) ... возможно, внутренний драйвер отличается от sqlite-jdbc ...
источник
Обычно (как и в mysql / postgres) я храню даты в int (mysql / post) или текстовом (sqlite), чтобы сохранить их в формате отметки времени.
Затем я преобразую их в объекты Date и выполняю действия на основе пользователя TimeZone.
источник
Лучший способ хранения
date
в SQlite DB - сохранить текущийDateTimeMilliseconds
. Ниже приведен фрагмент кода для этого:Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .
Следующий шаг - когда вы хотите извлечь данные из БД, вам необходимо преобразовать соответствующие даты и миллисекунды в соответствующие даты. Ниже приведен пример кода, чтобы сделать то же самое.
Надеюсь, это поможет всем! :)
источник
1 -Точно так же, как сказал StErMi.
2 - Пожалуйста, прочитайте это: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
посмотреть здесь:
Query () в SQLiteDatabase
4 - см. Ответ 3
источник
Я предпочитаю это. Это не лучший способ, но быстрое решение.
источник
источник