Saya mengalami masalah dalam menangani tanggal pada aplikasi Android yang menggunakan SQLite. Saya punya beberapa pertanyaan:
- Jenis apa yang harus saya gunakan untuk menyimpan tanggal dalam SQLite (teks, integer, ...)?
- Diberi cara terbaik untuk menyimpan tanggal, bagaimana cara menyimpannya dengan benar menggunakan ContentValues?
- Apa cara terbaik untuk mengambil tanggal dari database SQLite?
- Bagaimana cara memilih sql pada SQLite, memesan hasilnya berdasarkan tanggal?
Jawaban:
Anda dapat menggunakan bidang teks untuk menyimpan tanggal dalam
SQLite
.Menyimpan tanggal dalam format UTC, defaultnya jika Anda gunakan
datetime('now')
(yyyy-MM-dd HH:mm:ss)
kemudian akan mengizinkan pengurutan berdasarkan kolom tanggal.Mengambil tanggal sebagai string dari
SQLite
Anda kemudian dapat memformat / mengonversinya sesuai kebutuhan ke dalam format regionalisasi lokal menggunakan Kalender atauandroid.text.format.DateUtils.formatDateTime
metode.Berikut adalah metode formatter regional yang saya gunakan;
sumber
Cara terbaik adalah menyimpan tanggal sebagai angka, diterima dengan menggunakan perintah Kalender.
Kenapa melakukan ini? Pertama-tama, mendapatkan nilai dari rentang tanggal itu mudah. Konversikan tanggal Anda menjadi milidetik, lalu kueri dengan tepat. Menyortir berdasarkan tanggal juga mudah. Panggilan untuk mengonversi berbagai format juga mudah, seperti yang saya sertakan. Intinya adalah, dengan metode ini, Anda dapat melakukan apa pun yang perlu Anda lakukan, tidak ada masalah. Akan sedikit sulit untuk membaca nilai mentah, tetapi lebih dari sekadar membuat sedikit kerugian dengan mudah dibaca dan digunakan mesin. Dan pada kenyataannya, relatif mudah untuk membangun pembaca (Dan saya tahu ada beberapa di luar sana) yang secara otomatis akan mengubah tanda waktu menjadi tanggal sehingga mudah dibaca.
Perlu disebutkan bahwa nilai-nilai yang keluar dari ini harus panjang, bukan int. Integer dalam sqlite dapat berarti banyak hal, mulai dari 1-8 byte, tetapi untuk hampir semua tanggal 64 bit, atau panjang, itulah yang berhasil.
EDIT: Seperti yang telah ditunjukkan dalam komentar, Anda harus menggunakan
cursor.getLong()
untuk mendapatkan cap waktu dengan benar jika Anda melakukan ini.sumber
Untuk menyimpan, Anda bisa menggunakan metode utilitas
seperti itu:
Metode utilitas lain menangani pemuatan
dapat digunakan seperti ini:
Pemesanan berdasarkan tanggal adalah klausa SQL ORDER sederhana (karena kami memiliki kolom numerik). Berikut ini akan memesan menurun (yaitu tanggal terbaru lebih dulu):
Selalu pastikan untuk menyimpan waktu UTC / GMT , terutama ketika bekerja dengan
java.util.Calendar
danjava.text.SimpleDateFormat
yang menggunakan zona waktu default (yaitu perangkat Anda).java.util.Date.Date()
aman digunakan karena menciptakan nilai UTC.sumber
SQLite dapat menggunakan tipe data teks, nyata, atau bilangan bulat untuk menyimpan tanggal. Terlebih lagi, setiap kali Anda melakukan kueri, hasilnya ditampilkan menggunakan format
%Y-%m-%d %H:%M:%S
.Sekarang, jika Anda memasukkan / memperbarui nilai tanggal / waktu menggunakan fungsi tanggal / waktu SQLite, Anda sebenarnya dapat menyimpan milidetik juga. Jika itu masalahnya, hasilnya ditampilkan menggunakan format
%Y-%m-%d %H:%M:%f
. Sebagai contoh:Sekarang, lakukan beberapa pertanyaan untuk memverifikasi apakah kami benar-benar dapat membandingkan waktu:
Anda dapat memeriksa
SELECT
menggunakan yang samacol2
dancol3
dan Anda akan mendapatkan hasil yang sama. Seperti yang Anda lihat, baris kedua (126 milidetik) tidak dikembalikan.Perhatikan bahwa
BETWEEN
itu inklusif, oleh karena itu ...... akan mengembalikan set yang sama.
Cobalah bermain-main dengan rentang tanggal / waktu yang berbeda dan semuanya akan berperilaku seperti yang diharapkan.
Bagaimana tanpa
strftime
fungsi?Bagaimana dengan tanpa
strftime
fungsi dan tanpa milidetik?Bagaimana dengan
ORDER BY
?Bekerja dengan baik.
Akhirnya, ketika berhadapan dengan operasi aktual dalam suatu program (tanpa menggunakan sqlite yang dapat dieksekusi ...)
BTW: Saya menggunakan JDBC (tidak yakin tentang bahasa lain) ... driver sqlite-jdbc v3.7.2 dari xerial - mungkin revisi yang lebih baru mengubah perilaku yang dijelaskan di bawah ini ... Jika Anda mengembangkan di Android, Anda tidak membutuhkan driver jdbc. Semua operasi SQL dapat dikirimkan menggunakan
SQLiteOpenHelper
.JDBC memiliki metode yang berbeda untuk mendapatkan nilai tanggal / waktu yang sebenarnya dari database:
java.sql.Date
,java.sql.Time
, danjava.sql.Timestamp
.Metode terkait di
java.sql.ResultSet
yang (jelas)getDate(..)
,getTime(..)
dangetTimestamp()
masing-masing.Sebagai contoh:
Karena SQLite tidak memiliki tipe data DATE / TIME / TIMESTAMP yang sebenarnya, ketiga metode ini mengembalikan nilai seolah-olah objek diinisialisasi dengan 0:
Jadi, pertanyaannya adalah: bagaimana kita dapat benar-benar memilih, menyisipkan, atau memperbarui objek Tanggal / Waktu / Stempel Waktu? Tidak ada jawaban yang mudah. Anda dapat mencoba kombinasi yang berbeda, tetapi mereka akan memaksa Anda untuk menanamkan fungsi SQLite di semua pernyataan SQL. Jauh lebih mudah untuk mendefinisikan kelas utilitas untuk mengubah teks menjadi objek Tanggal di dalam program Java Anda. Tetapi selalu ingat bahwa SQLite mengubah nilai tanggal apa pun menjadi UTC + 0000.
Singkatnya, meskipun aturan umum untuk selalu menggunakan tipe data yang benar, atau, bahkan bilangan bulat yang menunjukkan waktu Unix (milidetik sejak zaman), saya menemukan jauh lebih mudah menggunakan format SQLite default (
'%Y-%m-%d %H:%M:%f'
atau di Jawa'yyyy-MM-dd HH:mm:ss.SSS'
) daripada mempersulit semua pernyataan SQL Anda dengan Fungsi SQLite. Pendekatan sebelumnya jauh lebih mudah untuk dipertahankan.TODO: Saya akan memeriksa hasilnya ketika menggunakan getDate / getTime / getTimestamp di dalam Android (API15 atau lebih baik) ... mungkin driver internal berbeda dari sqlite-jdbc ...
sumber
Biasanya (sama seperti yang saya lakukan di mysql / postgres) Saya menyimpan tanggal di int (mysql / post) atau teks (sqlite) untuk menyimpannya dalam format timestamp.
Lalu saya akan mengonversinya menjadi objek Tanggal dan melakukan tindakan berdasarkan pengguna TimeZone
sumber
Cara terbaik untuk menyimpan
date
di SQlite DB adalah menyimpan saat iniDateTimeMilliseconds
. Di bawah ini adalah cuplikan kode untuk melakukannya_Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .
Langkah selanjutnya adalah, ketika Anda ingin mengambil data dari DB Anda perlu mengkonversi milidetik waktu tanggal masing-masing ke tanggal yang sesuai. Di bawah ini adalah cuplikan kode sampel untuk melakukan hal yang sama_
Semoga ini bisa membantu semua! :)
sumber
1 -Sangat seperti kata StErMi.
2 - Silakan baca ini: http://www.vogella.de/articles/AndroidSQLite/article.html
3 -
Lihat disini:
Kueri () dalam SQLiteDatabase
4 - lihat jawaban 3
sumber
Saya lebih memilih ini. Ini bukan cara terbaik, tetapi solusi cepat.
sumber
sumber