android menambah atau menghapus jam dari stempel waktu di database

Saya ingin mengurangi beberapa hari dari stempel waktu saya di Android.

Saya memiliki basis data SQLite dengan bidang tanggal bertipe long. Saat saya menjalankan kueri yang saya ucapkan date = date - (3 * 86400000), terkadang saya mengalami perbedaan satu jam saat mengonversinya menjadi tanggal yang dapat dibaca.

Tapi bagaimana ini mungkin? Apakah ini ada hubungannya dengan penghematan waktu siang hari selama satu jam di zona waktu saya?

Karena menurut saya aneh jika itu alasannya karena Anda melakukan perhitungan dengan dua nilai panjang dan setelah mengonversinya kembali ke waktu waktu seharusnya tidak ada masalah musim panas?


person randomizer    schedule 26.10.2012    source sumber
comment
Bagaimana kamu tahu ada perbedaan satu jam? Apakah Anda mengonversinya menjadi Date atau Calendar dan memeriksanya? Akan sangat membantu jika melihat beberapa contoh kode untuk mengetahui apa yang Anda lakukan.   -  person Steve Blackwell    schedule 27.10.2012
comment
Zona waktu dapat menjadi masalah jika salah satu zona waktu disetel sedangkan zona waktu lainnya tidak. Karena tanggal Java defaultnya adalah GMT, itu akan menjadi dasar Anda dalam mencari tahu siapa yang berada di zona waktu apa.   -  person dispake    schedule 27.10.2012


Jawaban (2)


Terima kasih atas balasannya tetapi saya menemukan solusinya. Tampaknya ketika Anda menambahkan hari dalam milidetik ke stempel waktu Anda dan ada perbedaan jam dalam pengaturan siang hari di antara keduanya, tanggal tersebut secara otomatis diperbaiki.

Ketika saya melakukan hal berikut, jamnya diabaikan:

Date d = new Date();
d.setDays(d.getDays() - 2);

Namun, saya akan merekomendasikan menggunakan perpustakaan Joda karena lebih fleksibel dan mudah digunakan.

person randomizer    schedule 29.10.2012
comment
FYI, kelas tanggal-waktu lama yang sangat merepotkan seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormat kini menjadi warisan, digantikan oleh java.time dibangun di Java 8 dan yang lebih baru . Lihat Tutorial oleh Oracle. - person Basil Bourque; 16.11.2018

tl;dr

Gunakan kelas java.time modern.

Jika yang Anda maksud adalah 3 hari seperti pada tanggal kalender, lakukan ini:

Instant                                // Represent a moment in UTC with a resolution of nanoseconds.
.ofEpochSecond( x )                    // Parse some number of whole seconds or milliseconds from the epoch reference of first moment of 1970 in UTC.
.atZone(                               // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "Pacific/Auckland" )    // Assign the time zone by which you want the context of their calendar for adding dates.
)                                      // Returns a `ZonedDateTime` object.
.plus(                                 // Move to another moment by adding a span-of-time.
    Period.ofDays( 3 )                 // Define a span of time as a number of days on the calendar (date) without regard for the length of a day.
)                                      // Returns another `ZonedDateTime` object.
.toInstant()                           // Adjust from a time zone to UTC. Same moment, different wall-clock time.
.toEpochSeconds()                      // or maybe `toEpochMillis` depending on your practice with your `long` number.

Tulis SQL Anda sebagai:

SELECT * FROM event_ WHERE when_ >= ? ;  -- Find events occurring later than the passed moment.

Di Java dengan JDBC 4.2 atau lebih baru:

myPreparedStatement.setObject( 1 , secondsSinceEpoch ) ;  // Pass seconds calculated above.

Pengambilan.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Hitung dari zaman

Angka tipe long Anda mungkin merupakan hitungan detik atau milidetik penuh sejak tanggal referensi zaman.

Jika zaman yang Anda pilih kebetulan digunakan oleh “Waktu Unix”, momen pertama tahun 1970 di UTC, 01-01-1970T00:00:00Z, maka kita dapat mengurai di Java sebagai Instant. Instant adalah momen pada garis waktu dalam UTC dengan resolusi nanodetik. Instant secara internal adalah sepasang angka: hitungan detik penuh sejak zaman, ditambah sepersekian detik sebagai hitungan nanodetik.

Instant instant = Instant.ofEpochMilli( x ) ;

…or:

Instant instant = Instant.ofEpochSecond( x ) ;

Sehari bukan 24 jam

Sehari, seperti halnya tanggal di kalender, tidak sama dengan 24 jam. Anomali dalam cara politisi menentukan zona waktu seperti Waktu Musim Panas (DST) berarti satu hari mungkin 23, 23,5, 24, 25, atau jumlah jam-menit-detik lainnya.

Duration

Jika Anda ingin menambahkan potongan 24 jam, gunakan Duration.

Duration d = Duration.ofDays( 3 ) ;  // `Duration` defines a “day” as being a 24-hours without regard for the calendar dates.

Atau tentukan dalam jam, yang memiliki hasil yang sama di kelas Duration tetapi akan lebih jelas maksud dan pemahaman Anda.

Duration d = Duration.ofHours( 3 * 24 ) ;  // Same effect as the `Duration.ofDays( 3 )` seen above.

Tambahkan ke Instant Anda.

Instant instantLater = instant.plus( d ) ;

Period

Jika yang Anda maksud adalah satu hari sebagai penambahan satu hari di kalender, gunakan Period kelas. Kelas ini mewakili beberapa tahun-bulan-hari.

Period p = Period.ofDays( 3 ) ;  // `Period` defines a day as a date on the calendar without regard for its length in hours.

Kami tidak dapat menambahkannya ke Instant tanpa memperhatikan masalah zona waktu. Jika ditambahkan ke Instant yang selalu dalam UTC kita akan menggunakan kalender UTC. Misalnya, menambahkan hari ke suatu nilai dalam UTC mungkin diterjemahkan menjadi “besok” di India, namun tetap menjadi “kemarin” di Québec. Zona waktu sangat penting dalam menentukan tanggal. Untuk momen tertentu, tanggalnya bervariasi di seluruh dunia berdasarkan zona.

Jika tidak ada zona waktu yang ditentukan, JVM secara implisit menerapkan zona waktu default saat ini. Default tersebut dapat berubah kapan saja selama runtime(!), sehingga hasil Anda mungkin berbeda. Lebih baik tentukan zona waktu yang diinginkan/diharapkan Anda secara eksplisit sebagai argumen.

Tentukan nama zona waktu yang tepat dalam format continent/region, seperti America/Montreal, Africa/Casablanca, atau Pacific/Auckland . Jangan pernah menggunakan singkatan 2-4 huruf seperti EST atau IST karena bukan zona waktu sebenarnya, tidak terstandarisasi, dan bahkan tidak unik(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  

Jika Anda ingin menggunakan zona waktu default JVM saat ini, mintalah dan sampaikan sebagai argumen. Jika dihilangkan, default JVM saat ini diterapkan secara implisit. Sebaiknya jelaskan secara eksplisit, karena defaultnya dapat diubah kapan saja selama runtime dengan kode apa pun di thread mana pun pada aplikasi apa pun dalam JVM.

Terapkan ZoneId Anda ke Instant untuk mendapatkan ZonedDateTime.

ZonedDateTime zdt = instant.atZone( z ) ;

Sekarang Anda dapat menambahkan hari ke ZonedDateTime dan kalender yang digunakan oleh masyarakat di wilayah tersebut akan diperhitungkan.

ZonedDateTime zdtLater = zdt.plus( p ) ;  // By “later” we assume the number of days in the `Period` is positive. Alternatively, a `Period` could go backwards in time with a negative number of days.

Untuk menyesuaikan kembali ke UTC, ekstrak Instant. Kita masih mempunyai momen yang sama, titik yang sama di timeline, namun dengan waktu jam dinding yang berbeda.

Instant instantLater = zdtLater.toInstant() ;  // Same moment, different wall-clock time.

Waktu yang berlalu antara zdt dan zdtLater mungkin ( 3 * 24 ) jam atau tidak. Jika peralihan DST terjadi selama waktu tersebut, jumlah jamnya akan menjadi ( ( 3 * 24 ) - 1 ) pada “Musim Semi Menjelang” di awal tahun, atau ( ( 3 * 24 ) + 1 ) pada “Musim Gugur” di musim gugur.


Tentang java.time

java.time dibangun di Java 8 dan yang lebih baru. Kelas-kelas ini menggantikan kelas tanggal-waktu warisan lama yang merepotkan seperti java.util.Date, Calendar, & SimpleDateFormat.

Proyek Joda-Time, kini berada di mode pemeliharaan, menyarankan migrasi ke java.time kelas.

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle. Dan cari Stack Overflow untuk mendapatkan banyak contoh dan penjelasan. Spesifikasinya adalah JSR 310.

Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau lebih baru. Tidak perlu string, tidak perlu kelas java.sql.*.

Di mana mendapatkan kelas java.time?

Proyek ThreeTen-Extra memperluas java.time dengan kelas tambahan . Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan java.time di masa depan. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval, YearWeek, YearQuarter, dan selengkapnya.

person Basil Bourque    schedule 16.11.2018