Ich habe Probleme beim Arbeiten mit Datumsangaben in meiner Android-Anwendung, die SQLite verwendet. Ich habe ein paar Fragen:
- Welchen Typ soll ich zum Speichern von Datumsangaben in SQLite verwenden (Text, Ganzzahl, ...)?
- Wie speichere ich Datumsangaben mit ContentValues ordnungsgemäß?
- Wie kann das Datum am besten aus der SQLite-Datenbank abgerufen werden?
- Wie kann man eine SQL-Auswahl in SQLite treffen und die Ergebnisse nach Datum sortieren?
Antworten:
Sie können ein Textfeld verwenden, um Daten darin zu speichern
SQLite
.Wenn Sie Datumsangaben im UTC-Format speichern, können Sie standardmäßig nach der
datetime('now')
(yyyy-MM-dd HH:mm:ss)
Datumsspalte sortieren.Wenn Sie Datumsangaben als Zeichenfolgen abrufen
SQLite
, können Sie sie nach Bedarf mithilfe des Kalenders oder derandroid.text.format.DateUtils.formatDateTime
Methode formatieren / in lokale regionalisierte Formate konvertieren .Hier ist eine regionalisierte Formatierungsmethode, die ich verwende.
quelle
Am besten speichern Sie die Daten als Zahl, die Sie mit dem Befehl Kalender erhalten.
Warum das? Zunächst einmal ist es einfach, Werte aus einem Datumsbereich abzurufen. Konvertieren Sie einfach Ihr Datum in Millisekunden und fragen Sie dann entsprechend ab. Das Sortieren nach Datum ist ähnlich einfach. Die Aufrufe zum Konvertieren zwischen verschiedenen Formaten sind ebenfalls einfach, wie ich eingeschlossen habe. Unterm Strich können Sie mit dieser Methode alles tun, was Sie tun müssen, ohne Probleme. Es wird etwas schwierig sein, einen Rohwert zu lesen, aber es macht diesen kleinen Nachteil mehr als wett, weil es leicht maschinenlesbar und verwendbar ist. Tatsächlich ist es relativ einfach, einen Reader zu erstellen (und ich weiß, dass es einige gibt), der das Zeit-Tag automatisch in ein solches konvertiert, um das Lesen zu vereinfachen.
Es ist erwähnenswert, dass die Werte, die daraus entstehen, lang sein sollten, nicht int. Ganzzahl in SQLite kann viele Dinge bedeuten, alles von 1 bis 8 Bytes, aber für fast alle Daten funktionieren 64 Bit oder eine lange.
BEARBEITEN: Wie in den Kommentaren erwähnt, müssen Sie den verwenden
cursor.getLong()
, um den Zeitstempel richtig zu erhalten, wenn Sie dies tun.quelle
int
. Aber wenn Sie das Datum von einem Cursor erhalten, den Sie verwendencursor.getLong()
- Lassen Sie mich fragen: Warum ist das kein Problem? Ich dachte, einint
könnte nicht so viele Informationen speichern wie einLong
. Wie funktioniert das genau? Ist die SQLiteint
etwas Besonderes ...?Zum Speichern können Sie eine Dienstprogrammmethode verwenden
wie so:
Eine andere Gebrauchsmethode kümmert sich um das Laden
kann wie folgt verwendet werden:
Die Reihenfolge nach Datum ist eine einfache SQL ORDER-Klausel (da wir eine numerische Spalte haben). Folgendes wird absteigend sortiert (das neueste Datum steht an erster Stelle):
Stellen Sie immer sicher, dass Sie die UTC / GMT-Zeit speichern , insbesondere wenn Sie mit der Standardzeitzone (dh der Zeitzone Ihres Geräts) arbeiten
java.util.Calendar
undjava.text.SimpleDateFormat
diese verwenden.java.util.Date.Date()
ist sicher zu verwenden, da es einen UTC-Wert erstellt.quelle
SQLite kann Text-, Real- oder Integer-Datentypen zum Speichern von Datumsangaben verwenden. Darüber hinaus werden die Ergebnisse bei jeder Abfrage im Format angezeigt
%Y-%m-%d %H:%M:%S
.Wenn Sie jetzt Datums- / Zeitwerte mithilfe von SQLite-Datums- / Uhrzeitfunktionen einfügen / aktualisieren, können Sie auch Millisekunden speichern. In diesem Fall werden die Ergebnisse im Format angezeigt
%Y-%m-%d %H:%M:%f
. Beispielsweise:Führen Sie nun einige Abfragen durch, um zu überprüfen, ob wir die Zeiten tatsächlich vergleichen können:
Sie können das gleiche
SELECT
mitcol2
und überprüfencol3
und erhalten die gleichen Ergebnisse. Wie Sie sehen können, wird die zweite Zeile (126 Millisekunden) nicht zurückgegeben.Beachten Sie, dass dies
BETWEEN
inklusive ist, daher ...... gibt den gleichen Satz zurück.
Versuchen Sie, mit verschiedenen Datums- / Zeitbereichen herumzuspielen, und alles wird sich wie erwartet verhalten.
Was ist ohne
strftime
Funktion?Was ist ohne
strftime
Funktion und ohne Millisekunden?Was ist mit
ORDER BY
?Funktioniert gut.
Schließlich, wenn es um tatsächliche Operationen innerhalb eines Programms geht (ohne die ausführbare SQLite-Datei zu verwenden ...)
Übrigens: Ich verwende JDBC (bei anderen Sprachen nicht sicher) ... den sqlite-jdbc-Treiber v3.7.2 von xerial - möglicherweise ändern neuere Versionen das unten erläuterte Verhalten ... Wenn Sie in Android entwickeln, tun Sie dies nicht brauche einen JDBC-Treiber. Alle SQL-Operationen können mit dem gesendet werden
SQLiteOpenHelper
.JDBC hat verschiedene Methoden aktuelle Datum / Zeit - Werte aus einer Datenbank zu erhalten:
java.sql.Date
,java.sql.Time
, undjava.sql.Timestamp
.Die zugehörigen Verfahren in
java.sql.ResultSet
sind (natürlich)getDate(..)
,getTime(..)
undgetTimestamp()
jeweils.Beispielsweise:
Da SQLite keinen tatsächlichen Datentyp DATE / TIME / TIMESTAMP hat, geben alle diese 3 Methoden Werte zurück, als ob die Objekte mit 0 initialisiert worden wären:
Die Frage ist also: Wie können wir Datums- / Zeit- / Zeitstempelobjekte tatsächlich auswählen, einfügen oder aktualisieren? Es gibt keine einfache Antwort. Sie können verschiedene Kombinationen ausprobieren, diese zwingen Sie jedoch dazu, SQLite-Funktionen in alle SQL-Anweisungen einzubetten. Es ist viel einfacher, eine Dienstprogrammklasse zu definieren, um Text in Datumsobjekte in Ihrem Java-Programm umzuwandeln. Denken Sie jedoch immer daran, dass SQLite einen beliebigen Datumswert in UTC + 0000 umwandelt.
Zusammenfassend lässt sich sagen, dass ich trotz der allgemeinen Regel, immer den richtigen Datentyp oder sogar Ganzzahlen zu verwenden, die die Unix-Zeit (Millisekunden seit der Epoche) angeben, die Verwendung des Standard-SQLite-Formats (
'%Y-%m-%d %H:%M:%f'
oder in Java'yyyy-MM-dd HH:mm:ss.SSS'
) viel einfacher finde , als alle Ihre SQL-Anweisungen zu komplizieren SQLite-Funktionen. Der erstere Ansatz ist viel einfacher zu pflegen.TODO: Ich werde die Ergebnisse überprüfen, wenn ich getDate / getTime / getTimestamp in Android (API15 oder besser) verwende ... vielleicht unterscheidet sich der interne Treiber von sqlite-jdbc ...
quelle
Normalerweise (wie in MySQL / Postgres) speichere ich Datumsangaben in Int (MySQL / Post) oder Text (SQLite), um sie im Zeitstempelformat zu speichern.
Dann werde ich sie in Datumsobjekte konvertieren und Aktionen basierend auf dem Benutzer TimeZone ausführen
quelle
Der beste Weg, um
date
in SQlite DB zu speichern, ist das Speichern des aktuellenDateTimeMilliseconds
. Unten finden Sie das Code-Snippet, um dies zu tunNow, your data (date is in currentTimeMilliseconds) is get inserted in DB .
Der nächste Schritt ist, wenn Sie Daten aus der Datenbank abrufen möchten, müssen Sie die entsprechenden Datums- und Uhrzeit-Millisekunden in das entsprechende Datum konvertieren. Unten finden Sie das Beispielcode-Snippet, um dasselbe zu tun
Hoffe das wird allen helfen! :) :)
quelle
1 - Genau wie StErMi sagte.
2 - Bitte lesen Sie dies: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
siehe hier:
Query () in SQLiteDatabase
4 - siehe Antwort 3
quelle
Ich bevorzuge das. Dies ist nicht der beste Weg, aber eine schnelle Lösung.
quelle
quelle