Estou com problemas para trabalhar com datas no meu aplicativo Android que usa SQLite. Eu tenho algumas perguntas:
- Que tipo devo usar para armazenar datas no SQLite (texto, número inteiro, ...)?
- Dada a melhor maneira de armazenar datas, como faço para armazená-lo corretamente usando o ContentValues?
- Qual é a melhor maneira de recuperar a data do banco de dados SQLite?
- Como fazer um sql selecionar no SQLite, ordenando os resultados por data?
Respostas:
Você pode usar um campo de texto para armazenar datas
SQLite
.Armazenando datas no formato UTC, o padrão se você usar
datetime('now')
(yyyy-MM-dd HH:mm:ss)
permitirá a classificação pela coluna de datas.Recuperando datas como seqüências de caracteres,
SQLite
você pode formatá-las / convertê-las conforme necessário em formatos regionais regionalizados usando o Calendário ou oandroid.text.format.DateUtils.formatDateTime
método.Aqui está um método formatador regionalizado que eu uso;
fonte
A melhor maneira é armazenar as datas como um número, recebido usando o comando Calendário.
Por que fazer isso? Primeiro de tudo, é fácil obter valores de um período. Basta converter sua data em milissegundos e, em seguida, consultar adequadamente. Classificar por data é igualmente fácil. As chamadas para converter entre vários formatos também são fáceis, como eu incluí. Resumindo, com este método, você pode fazer o que precisar, sem problemas. Será um pouco difícil ler um valor bruto, mas mais do que compõe essa pequena desvantagem de ser facilmente legível e utilizável pela máquina. E, de fato, é relativamente fácil criar um leitor (e eu sei que existem alguns por aí) que converterão automaticamente a marca de tempo para data como tal, para facilitar a leitura.
Vale ressaltar que os valores resultantes disso devem ser longos, não int. Inteiro no sqlite pode significar muitas coisas, de 1 a 8 bytes, mas para quase todas as datas 64 bits, ou um longo, é o que funciona.
EDIT: Como foi apontado nos comentários, você deve usar o
cursor.getLong()
para obter o registro de data e hora corretamente se fizer isso.fonte
Para armazenar, você pode usar um método utilitário
igual a:
Outro método utilitário cuida do carregamento
pode ser usado assim:
A ordenação por data é uma simples cláusula SQL ORDER (porque temos uma coluna numérica). A ordem a seguir será decrescente (a data mais recente será a primeira):
Sempre certifique-se de armazenar a hora UTC / GMT , especialmente quando estiver trabalhando
java.util.Calendar
ejava.text.SimpleDateFormat
que use o fuso horário padrão (por exemplo, o seu dispositivo).java.util.Date.Date()
é seguro de usar, pois cria um valor UTC.fonte
O SQLite pode usar tipos de dados de texto, reais ou inteiros para armazenar datas. Ainda mais, sempre que você realiza uma consulta, os resultados são mostrados usando o formato
%Y-%m-%d %H:%M:%S
.Agora, se você inserir / atualizar valores de data / hora usando as funções de data / hora do SQLite, também poderá armazenar milissegundos. Se for esse o caso, os resultados são mostrados usando o formato
%Y-%m-%d %H:%M:%f
. Por exemplo:Agora, faça algumas consultas para verificar se conseguimos comparar os tempos:
Você pode verificar o mesmo
SELECT
usandocol2
ecol3
e você vai obter os mesmos resultados. Como você pode ver, a segunda linha (126 milissegundos) não é retornada.Observe que
BETWEEN
é inclusivo, portanto ...... retornará o mesmo conjunto.
Tente brincar com diferentes intervalos de data / hora e tudo se comportará conforme o esperado.
E sem
strftime
função?Que tal sem
strftime
função e sem milissegundos?Que tal
ORDER BY
?Funciona muito bem.
Finalmente, ao lidar com operações reais dentro de um programa (sem usar o executável sqlite ...)
BTW: Estou usando JDBC (não tenho certeza sobre outros idiomas) ... o driver sqlite-jdbc v3.7.2 da xerial - talvez as revisões mais recentes alterem o comportamento explicado abaixo ... Se você está desenvolvendo no Android, não precisa precisa de um driver jdbc. Todas as operações SQL podem ser enviadas usando o
SQLiteOpenHelper
.JDBC tem diferentes métodos para obter valores de data / hora real a partir de um banco de dados:
java.sql.Date
,java.sql.Time
, ejava.sql.Timestamp
.Os métodos relacionados em
java.sql.ResultSet
são (obviamente)getDate(..)
,getTime(..)
e,getTimestamp()
respectivamente.Por exemplo:
Como o SQLite não possui um tipo de dados DATE / TIME / TIMESTAMP real, todos esses três métodos retornam valores como se os objetos fossem inicializados com 0:
Portanto, a pergunta é: como podemos realmente selecionar, inserir ou atualizar objetos Data / Hora / Data e Hora? Não há resposta fácil. Você pode tentar combinações diferentes, mas elas o forçarão a incorporar funções SQLite em todas as instruções SQL. É muito mais fácil definir uma classe de utilitário para transformar texto em objetos Date dentro do seu programa Java. Mas lembre-se sempre de que o SQLite transforma qualquer valor de data em UTC + 0000.
Em resumo, apesar da regra geral de sempre usar o tipo de dados correto ou mesmo números inteiros que denotam tempo Unix (milissegundos desde a época), acho muito mais fácil usar o formato SQLite padrão (
'%Y-%m-%d %H:%M:%f'
ou em Java'yyyy-MM-dd HH:mm:ss.SSS'
) para complicar todas as suas instruções SQL com Funções SQLite. A abordagem anterior é muito mais fácil de manter.TODO: Vou verificar os resultados ao usar getDate / getTime / getTimestamp dentro do Android (API15 ou melhor) ... talvez o driver interno seja diferente do sqlite-jdbc ...
fonte
Normalmente (o mesmo que no mysql / postgres) armazeno datas em int (mysql / post) ou texto (sqlite) para armazená-las no formato de carimbo de data / hora.
Então eu os converterei em objetos Date e executarei ações com base no usuário TimeZone
fonte
A melhor maneira de armazenar
date
no SQlite DB é armazenar o atualDateTimeMilliseconds
. Abaixo está o snippet de código para fazer isso_Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .
A próxima etapa é que, quando você deseja recuperar dados do banco de dados, precisa converter os respectivos milissegundos de data e hora na data correspondente. Abaixo está o exemplo de trecho de código para fazer o mesmo_
Espero que isso ajude a todos! :)
fonte
1-Exatamente como StErMi disse.
2 - Leia o seguinte: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
Veja aqui:
Query () no SQLiteDatabase
4 - ver resposta 3
fonte
Eu prefiro isso. Esta não é a melhor maneira, mas uma solução rápida.
fonte
fonte