La meilleure façon de travailler avec des dates dans Android SQLite
J'ai un peu de mal à travailler avec des dates sur mon application Android qui utilise SQLite.
J'ai quelques questions:
- Quel type dois-je utiliser pour stocker des dates dans SQLite (texte, entier, ...)?
- Donné le meilleur moyen de stocker des dates comment dois-je le conserver correctement à l'aide de ContentValues?
- Quelle est la meilleure façon de récupérer la date à partir de la base de données SQLite?
- Comment faire un select sql sur SQLite, trier les résultats par date?
- Juste utiliser le Calendrier de la classe et de ses membres en temps (ce qui représente le nombre de millisecondes écoulées depuis le 1/1/1970). Il y a des fonctions de membre de la mutation de la valeur de temps en lisible cordes.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser un champ de texte pour enregistrer des dates dans
SQLite
.L'enregistrement des dates au format UTC, la valeur par défaut si vous utilisez
datetime('now')
(yyyy-MM-dd HH:mm:ss)
permettra alors de tri par la colonne date.De la récupération des dates comme des chaînes de
SQLite
vous pouvez ensuite le format/convertir en tant que de besoin dans les locaux de la régionalisation des formats à l'aide du Calendrier ou de laandroid.text.format.DateUtils.formatDateTime
méthode.Voici une régionalisation formateur méthode que j'utilise;
Le meilleur moyen est de stocker les dates sous forme de nombre, reçu en utilisant le Calendrier de commande.
Pourquoi faire cela? Tout d'abord, l'obtention de valeurs à partir d'une plage de dates est facile. Il suffit de convertir votre date en millisecondes, et ensuite d'interroger de manière appropriée. Le tri par date est de même facile. Les appels à convertir entre les différents formats sont également de la même manière facile, comme je l'ai compris. Ligne de fond est que, avec cette méthode, vous pouvez faire tout ce que vous devez faire, pas de problèmes. Il sera un peu difficile à lire une valeur brute, mais il fait plus de place qu'un léger inconvénient d'être facilement lisible à la machine et utilisable. Et en fait, il est relativement facile de construire un lecteur (Et je sais qu'il ya certains là-bas) qui va les convertir automatiquement l'étiquette de temps à ce jour en tant que tel pour faciliter la lecture.
Il est important de mentionner que les valeurs qui ressortent de ce doit être long, pas de type int. Entier en sqlite peut signifier beaucoup de choses, allant de 1 à 8 octets, mais presque toutes les dates de 64 bits, ou un long, est ce qui fonctionne.
EDIT: Comme cela a été souligné dans les commentaires, vous devez utiliser le
cursor.getLong()
à bien obtenir le timestamp si vous faites cela.int
. Mais quand vous obtenez la date à partir d'un curseur vous utilisezcursor.getLong()
- Permettez-moi de vous poser une question: pourquoi n'est-ce pas un problème? J'ai pensé qu'uneint
ne pouvaient pas stocker autant d'informations que d'unLong
, alors, comment est-ce exactement le travail? Est le SQLiteint
quelque chose de spécial...?int
est un terme très vague. Cela dépend vraiment de la langue, et le même système d'exploitation. Voir sqlite.org/datatype3.html, ce qui indique un nombre entier dans sqlite peut être de 1 à 8 octets, selon les besoins.Pour le stockage, vous pouvez utiliser un utilitaire méthode
comme suit:
Une autre méthode utilitaire prend en charge le chargement
peut être utilisée comme ceci:
De la commande par jour est simple SQL La clause ORDER (parce que nous avons une colonne numérique). Le suivant sera l'ordre décroissant (c'est le plus récent date va d'abord):
Assurez-vous de toujours stocker le UTC/GMT, surtout lorsque l'on travaille avec
java.util.Calendar
etjava.text.SimpleDateFormat
que l'utilisation de la valeur par défaut (c'est à dire de votre appareil) fuseau horaire.java.util.Date.Date()
est sûr à utiliser car il crée une valeur UTC.SQLite peut utiliser du texte, des réels, ou des types de données entier pour stocker des dates.
Plus encore, chaque fois que vous effectuez une requête, les résultats sont présentés en utilisant le format
%Y-%m-%d %H:%M:%S
.Maintenant, si vous insérer/mettre à jour les valeurs de date/heure à l'aide de SQLite date/heure de fonctions, vous pouvez stocker millisecondes ainsi.
Si c'est le cas, les résultats sont présentés en utilisant le format
%Y-%m-%d %H:%M:%f
.Par exemple:
Maintenant, de faire quelques requêtes pour vérifier si nous sommes réellement en mesure de comparer les temps:
Vous pouvez vérifier dans le même
SELECT
à l'aide decol2
etcol3
et vous obtiendrez les mêmes résultats.Comme vous pouvez le voir, la deuxième ligne (126 millisecondes) n'est pas retourné.
Noter que
BETWEEN
est inclus, donc...... sera de retour le même jeu.
Essayer de jouer avec les différents date/heure des plages et tout ce qui va se comporter comme prévu.
Ce sujet sans
strftime
fonction?Ce sujet sans
strftime
fonction et pas millisecondes?Ce sujet
ORDER BY
?Fonctionne très bien.
Enfin, lorsqu'ils traitent avec les opérations dans un programme (sans l'aide de l'sqlite exécutable...)
BTW: je suis à l'aide de JDBC (pas sûr d'autres langues)... l'sqlite-pilote jdbc v3.7.2 à partir de xerial - peut-être que les nouvelles versions de modifier le comportement est expliqué ci-dessous...
Si vous êtes en développement dans Android, vous n'avez pas besoin d'un jdbc-pilote. Toutes les opérations SQL peuvent être soumis en utilisant le
SQLiteOpenHelper
.JDBC a différentes méthodes pour obtenir de réelles valeurs de date/heure à partir d'une base de données:
java.sql.Date
,java.sql.Time
, etjava.sql.Timestamp
.Les méthodes associées à
java.sql.ResultSet
sont (évidemment)getDate(..)
,getTime(..)
, etgetTimestamp()
respectivement.Par exemple:
Depuis SQLite n'a pas de réelle DATE/HEURE/type de données TIMESTAMP l'ensemble de ces 3 méthodes retournent des valeurs comme si les objets sont initialisés à 0:
Donc, la question est: comment pouvons-nous réellement select, insert, ou la mise à jour de la Date/Heure/Timestamp objets? Il n'y a pas de réponse facile.
Vous pouvez essayer différentes combinaisons, mais ils vont vous forcer à intégrer SQLite fonctions dans toutes les instructions SQL. Il est beaucoup plus facile de définir une classe utilitaire pour transformer du texte à la Date d'objets à l'intérieur de votre programme Java. Mais rappelez-vous toujours que SQLite transforme n'importe quelle valeur de date au format UTC+0000.
En résumé, en dépit de la règle générale de toujours utiliser le type de données approprié ou, encore entiers indiquant le temps Unix (le nombre de millisecondes depuis l'époque), je le trouve beaucoup plus facile en utilisant la valeur par défaut format SQLite (
'%Y-%m-%d %H:%M:%f'
ou en Java'yyyy-MM-dd HH:mm:ss.SSS'
) plutôt compliquer toutes vos instructions SQL avec SQLite fonctions. La première approche est beaucoup plus facile à entretenir.TODO: je vais vérifier les résultats lors de l'utilisation de la fonction getDate/getTime/méthode gettimestamp à l'intérieur d'Android (API15 ou mieux)... peut-être que le pilote interne est différente de sqlite-jdbc...
Généralement (même comme je le fais dans mysql/postgres) je stocke les dates dans int(mysql/post) ou texte(sqlite) pour les stocker dans le format d'horodatage.
Alors je vais les convertir en objets Date et effectuer des actions basées sur le Fuseau horaire
Meilleure façon de conserver les
date
dans SQlite DB est de stocker de l'actuelDateTimeMilliseconds
. Ci-dessous l'extrait de code pour faire so_Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .
Prochaine étape est, lorsque vous souhaitez récupérer des données à partir de DB-vous besoin pour convertir la date respective de temps de quelques millisecondes à la date correspondante. Ci-dessous l'exemple d'un extrait de code pour faire la same_
Espérons que cela permettra à tous! 🙂
1 -Exactement comme StErMi dit.
2 - Veuillez lire ceci: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
voir ici:
Query() dans SQLiteDatabase
4 - voir la réponse 3
Je préfère cela. Ce n'est pas le meilleur moyen, mais une solution rapide.