Mam problem z pracą z datami w mojej aplikacji na Androida korzystającej z SQLite. Mam kilka pytań:
- Jakiego typu powinienem używać do przechowywania dat w SQLite (tekst, liczba całkowita, ...)?
- Biorąc pod uwagę najlepszy sposób na przechowywanie dat, w jaki sposób przechowuję go prawidłowo za pomocą ContentValues?
- Jaki jest najlepszy sposób na pobranie daty z bazy danych SQLite?
- Jak wybrać SQL w SQLite, sortując wyniki według daty?
Odpowiedzi:
Możesz użyć pola tekstowego do przechowywania dat
SQLite
.Przechowywanie dat w formacie UTC, domyślnie, jeśli użyjesz,
datetime('now')
(yyyy-MM-dd HH:mm:ss)
pozwoli następnie sortować według kolumny daty.Pobieranie dat jako ciągów znaków
SQLite
można następnie sformatować / przekonwertować zgodnie z wymaganiami do lokalnych formatów regionalnych za pomocą Kalendarza lubandroid.text.format.DateUtils.formatDateTime
metody.Oto metoda formatowania regionalnego, której używam;
źródło
Najlepszym sposobem jest przechowywanie dat jako liczb otrzymanych za pomocą polecenia Kalendarz.
Czemu to robić? Przede wszystkim uzyskiwanie wartości z zakresu dat jest łatwe. Wystarczy przekonwertować datę na milisekundy, a następnie odpowiednio zapytać. Sortowanie według daty jest podobnie łatwe. Wezwanie do konwersji między różnymi formatami jest również łatwe, jak to zawarłem. Podsumowując, dzięki tej metodzie możesz zrobić wszystko, co musisz zrobić, bez żadnych problemów. Odczytanie wartości surowej będzie nieco trudne, ale to nadrabia tę niewielką wadę, ponieważ jest łatwy do odczytu maszynowego i użytkowania. I w rzeczywistości stosunkowo łatwo jest zbudować czytnik (i wiem, że jest ich kilka), który automatycznie przekonwertuje znacznik czasu jako taki, aby był łatwy do odczytania.
Warto wspomnieć, że wartości, które z tego wynikają, powinny być długie, a nie int. Liczba całkowita w sqlite może oznaczać wiele rzeczy, od 1 do 8 bajtów, ale dla prawie wszystkich dat 64 bity lub długość jest tym, co działa.
EDYCJA: Jak wskazano w komentarzach, musisz użyć,
cursor.getLong()
aby poprawnie uzyskać znacznik czasu, jeśli to zrobisz.źródło
Do przechowywania możesz użyć metody narzędziowej
tak:
Innym sposobem użyteczności jest ładowanie
można użyć w następujący sposób:
Sortowanie według daty jest prostą klauzulą SQL ORDER (ponieważ mamy kolumnę numeryczną). Kolejność będzie malejąca (tzn. Najnowsza data jest pierwsza):
Zawsze upewnij się, aby zapisać czas UTC / GMT , zwłaszcza podczas pracy z
java.util.Calendar
ijava.text.SimpleDateFormat
które korzystają z domyślnego (czyli urządzenia) strefę czasową.java.util.Date.Date()
jest bezpieczny w użyciu, ponieważ tworzy wartość UTC.źródło
SQLite może używać tekstowych, rzeczywistych lub całkowitych typów danych do przechowywania dat. Co więcej, za każdym razem, gdy wykonujesz zapytanie, wyniki są wyświetlane przy użyciu formatu
%Y-%m-%d %H:%M:%S
.Teraz, jeśli wstawisz / zaktualizujesz wartości daty / godziny za pomocą funkcji daty / godziny SQLite, możesz faktycznie przechowywać milisekundy. W takim przypadku wyniki są wyświetlane przy użyciu formatu
%Y-%m-%d %H:%M:%f
. Na przykład:Teraz, wykonując kilka zapytań, aby sprawdzić, czy rzeczywiście jesteśmy w stanie porównać czasy:
Możesz to samo sprawdzić za
SELECT
pomocącol2
icol3
uzyskasz te same wyniki. Jak widać, drugi wiersz (126 milisekund) nie jest zwracany.Pamiętaj, że
BETWEEN
zawiera, dlatego ...... zwróci ten sam zestaw.
Spróbuj bawić się z różnymi zakresami dat i godzin, a wszystko będzie działać zgodnie z oczekiwaniami.
A co bez
strftime
funkcji?Co powiesz na bez
strftime
funkcji i bez milisekund?Co
ORDER BY
?Działa dobrze.
Wreszcie, gdy mamy do czynienia z rzeczywistymi operacjami w programie (bez korzystania z pliku wykonywalnego sqlite ...)
BTW: Używam JDBC (nie jestem pewien co do innych języków) ... sterownik sqlite-jdbc v3.7.2 z Xerial - być może nowsze wersje zmieniają zachowanie wyjaśnione poniżej ... Jeśli tworzysz w Androidzie, nie robisz tego potrzebujesz sterownika jdbc. Wszystkie operacje SQL można przesyłać za pomocą
SQLiteOpenHelper
.JDBC ma różne metody, aby uzyskać rzeczywiste wartości daty / godziny z bazy danych:
java.sql.Date
,java.sql.Time
, ijava.sql.Timestamp
.Związane z tym sposoby, w
java.sql.ResultSet
to (oczywiście)getDate(..)
,getTime(..)
igetTimestamp()
odpowiednio.Na przykład:
Ponieważ SQLite nie ma rzeczywistego typu danych DATE / TIME / TIMESTAMP, wszystkie te 3 metody zwracają wartości, tak jakby obiekty były inicjowane za pomocą 0:
Pytanie zatem brzmi: w jaki sposób możemy faktycznie wybierać, wstawiać lub aktualizować obiekty Data / Czas / Datownik?Nie ma łatwej odpowiedzi. Możesz wypróbować różne kombinacje, ale zmuszą cię do osadzenia funkcji SQLite we wszystkich instrukcjach SQL. O wiele łatwiej jest zdefiniować klasę narzędziową do przekształcania tekstu w obiekty Date w programie Java. Ale zawsze pamiętaj, że SQLite przekształca dowolną wartość daty na UTC + 0000.
Podsumowując, pomimo ogólnej zasady, aby zawsze używać poprawnego typu danych, a nawet liczb całkowitych oznaczających czas uniksowy (milisekund od epoki), znacznie łatwiej jest mi użyć domyślnego formatu SQLite (
'%Y-%m-%d %H:%M:%f'
lub w Javie'yyyy-MM-dd HH:mm:ss.SSS'
), aby skomplikować wszystkie instrukcje SQL za pomocą Funkcje SQLite. Pierwsze podejście jest znacznie łatwiejsze do utrzymania.DO ZROBIENIA: Sprawdzę wyniki podczas używania getDate / getTime / getTimestamp wewnątrz Androida (API15 lub nowszy) ... może wewnętrzny sterownik różni się od sqlite-jdbc ...
źródło
Zwykle (tak samo jak robię w mysql / postgres) przechowuję daty w liczbach int (mysql / post) lub tekstowych (sqlite), aby przechowywać je w formacie datownika.
Następnie przekonwertuję je na obiekty Date i wykonam działania na podstawie TimeZone użytkownika
źródło
Najlepszym sposobem przechowywania
date
w SQlite DB jest przechowywanie prąduDateTimeMilliseconds
. Poniżej znajduje się fragment kodu, aby to zrobić_Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .
Następnym krokiem jest, gdy chcesz pobrać dane z bazy danych, musisz przekonwertować odpowiednią milisekundę daty i godziny na odpowiednią datę. Poniżej znajduje się przykładowy fragment kodu, aby zrobić to samo_
Mam nadzieję, że to pomoże wszystkim! :)
źródło
1 - Dokładnie tak, jak powiedział StErMi.
2 - Przeczytaj to: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
Spójrz tutaj:
Query () w SQLiteDatabase
4 - patrz odpowiedź 3
źródło
Wolę to. To nie jest najlepszy sposób, ale szybkie rozwiązanie.
źródło
źródło