Tengo problemas para trabajar con fechas en mi aplicación de Android que usa SQLite. Tengo un par de preguntas:
- ¿Qué tipo debo usar para almacenar fechas en SQLite (texto, entero, ...)?
- Dada la mejor manera de almacenar fechas, ¿cómo lo almaceno correctamente usando ContentValues?
- ¿Cuál es la mejor manera de recuperar la fecha de la base de datos SQLite?
- ¿Cómo hacer una selección sql en SQLite, ordenando los resultados por fecha?
Respuestas:
Puede usar un campo de texto para almacenar fechas en
SQLite
.Almacenando fechas en formato UTC, el valor predeterminado si lo usa
datetime('now')
(yyyy-MM-dd HH:mm:ss)
permitirá entonces ordenar por la columna de fecha.Al recuperar fechas como cadenas
SQLite
, puede formatearlas / convertirlas según sea necesario en formatos regionalizados locales utilizando el Calendario o elandroid.text.format.DateUtils.formatDateTime
método.Aquí hay un método de formateador regionalizado que uso;
fuente
La mejor manera es almacenar las fechas como un número, recibido utilizando el comando Calendario.
¿Por qué hacer esto? En primer lugar, obtener valores de un rango de fechas es fácil. Simplemente convierta su fecha en milisegundos, y luego consulte adecuadamente. Ordenar por fecha es igualmente fácil. Las llamadas para convertir entre varios formatos también son también fáciles, como he incluido. La conclusión es que, con este método, puede hacer cualquier cosa que necesite hacer, sin problemas. Será un poco difícil leer un valor bruto, pero compensa con creces esa ligera desventaja de ser fácilmente legible y utilizable por máquina. Y de hecho, es relativamente fácil construir un lector (y sé que hay algunos por ahí) que convertirá automáticamente la etiqueta de tiempo a la fecha como tal para facilitar la lectura.
Vale la pena mencionar que los valores que surgen de esto deberían ser largos, no int. Entero en sqlite puede significar muchas cosas, desde 1 a 8 bytes, pero para casi todas las fechas lo que funciona es 64 bits o un largo.
EDITAR: como se ha señalado en los comentarios, debe usar el
cursor.getLong()
para obtener correctamente la marca de tiempo si hace esto.fuente
Para almacenar, puede usar un método de utilidad
al igual que:
Otro método de utilidad se encarga de la carga.
se puede usar así:
Ordenar por fecha es una simple cláusula SQL ORDER (porque tenemos una columna numérica). Lo siguiente ordenará descendente (es decir, la fecha más reciente va primero):
Siempre asegúrese de almacenar la hora UTC / GMT , especialmente cuando trabaje
java.util.Calendar
yjava.text.SimpleDateFormat
use la zona horaria predeterminada (es decir, la de su dispositivo).java.util.Date.Date()
es seguro de usar ya que crea un valor UTC.fuente
SQLite puede usar tipos de datos de texto, reales o enteros para almacenar fechas. Aún más, cada vez que realiza una consulta, los resultados se muestran usando el formato
%Y-%m-%d %H:%M:%S
.Ahora, si inserta / actualiza valores de fecha / hora utilizando las funciones de fecha / hora de SQLite, en realidad también puede almacenar milisegundos. Si ese es el caso, los resultados se muestran usando el formato
%Y-%m-%d %H:%M:%f
. Por ejemplo:Ahora, haciendo algunas consultas para verificar si realmente podemos comparar los tiempos:
Puede comprobar el mismo
SELECT
usandocol2
ycol3
y obtendrá los mismos resultados. Como puede ver, la segunda fila (126 milisegundos) no se devuelve.Tenga en cuenta que
BETWEEN
es inclusivo, por lo tanto ...... devolverá el mismo conjunto.
Intenta jugar con diferentes rangos de fecha / hora y todo se comportará como se espera.
¿Qué pasa sin
strftime
función?¿Qué pasa sin
strftime
función y sin milisegundos?¿Qué hay de
ORDER BY
?Funciona bien
Finalmente, cuando se trata de operaciones reales dentro de un programa (sin usar el ejecutable sqlite ...)
Por cierto: estoy usando JDBC (no estoy seguro acerca de otros idiomas) ... el controlador sqlite-jdbc v3.7.2 de xerial - tal vez las revisiones más recientes cambien el comportamiento explicado a continuación ... Si está desarrollando en Android, no Necesito un controlador jdbc. Todas las operaciones SQL se pueden enviar utilizando el
SQLiteOpenHelper
.JDBC tiene diferentes métodos para obtener valores reales de fecha / hora a partir de una base de datos:
java.sql.Date
,java.sql.Time
, yjava.sql.Timestamp
.Los métodos relacionados en
java.sql.ResultSet
son (obviamente)getDate(..)
,getTime(..)
ygetTimestamp()
respectivamente.Por ejemplo:
Como SQLite no tiene un tipo de datos DATE / TIME / TIMESTAMP real, estos 3 métodos devuelven valores como si los objetos se inicializaran con 0:
Entonces, la pregunta es: ¿cómo podemos seleccionar, insertar o actualizar objetos de fecha / hora / marca de tiempo?No hay una respuesta fácil. Puede probar diferentes combinaciones, pero lo obligarán a incrustar funciones SQLite en todas las instrucciones SQL. Es mucho más fácil definir una clase de utilidad para transformar texto en objetos Date dentro de su programa Java. Pero recuerde siempre que SQLite transforma cualquier valor de fecha a UTC + 0000.
En resumen, a pesar de la regla general de usar siempre el tipo de datos correcto o, incluso, enteros que denotan el tiempo de Unix (milisegundos desde la época), me resulta mucho más fácil usar el formato predeterminado de SQLite (
'%Y-%m-%d %H:%M:%f'
o en Java'yyyy-MM-dd HH:mm:ss.SSS'
) en lugar de complicar todas sus declaraciones SQL con Funciones SQLite. El primer enfoque es mucho más fácil de mantener.TODO: Comprobaré los resultados cuando use getDate / getTime / getTimestamp dentro de Android (API15 o superior) ... tal vez el controlador interno sea diferente de sqlite-jdbc ...
fuente
Por lo general (al igual que lo hago en mysql / postgres), almaceno las fechas en int (mysql / post) o texto (sqlite) para almacenarlas en el formato de marca de tiempo.
Luego los convertiré en objetos Date y realizaré acciones basadas en la zona horaria del usuario
fuente
La mejor manera de almacenar
date
en SQlite DB es almacenar el actualDateTimeMilliseconds
. A continuación se muestra el fragmento de código para hacerlo:Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .
El siguiente paso es, cuando desea recuperar datos de la base de datos, debe convertir la fecha y hora respectivas en milisegundos a la fecha correspondiente. A continuación se muestra el fragmento de código de muestra para hacer lo mismo_
Espero que esto ayude a todos! :)
fuente
1 -Exactamente como dijo StErMi.
2 - Por favor lea esto: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
mira aquí:
Query () en SQLiteDatabase
4 - ver respuesta 3
fuente
Prefiero esto. Esta no es la mejor manera, sino una solución rápida.
fuente
fuente