Java 8 menambahkan java.time API baru untuk bekerja dengan tanggal dan waktu ( JSR 310 ).
Saya memiliki tanggal dan waktu sebagai string (mis "2014-04-08 12:30"
.). Bagaimana saya bisa mendapatkan LocalDateTime
instance dari string yang diberikan?
Setelah saya selesai bekerja dengan LocalDateTime
objek: Bagaimana saya bisa mengubah LocalDateTime
instance kembali ke string dengan format yang sama seperti yang ditunjukkan di atas?
ZonedDateTime
lebih daripadaLocalDateTime
. Namanya kontra-intuitif; yangLocal
berarti setiap wilayah secara umum daripada zona waktu tertentu. Dengan demikian, suatuLocalDateTime
objek tidak terikat dengan garis waktu. Untuk memiliki makna, untuk mendapatkan momen tertentu pada garis waktu, Anda harus menerapkan zona waktu.LocalDateTime
vsZonedDateTime
vsOffsetDateTime
vsInstant
vsLocalDate
vsLocalTime
, bagaimana tetap tenang tentang mengapa begitu rumit dan bagaimana melakukannya dengan benar pada tembakan pertama.LocalDateTime
mungkin akan dinamaiZonelessOffsetlessDateTime
.Jawaban:
Tanggal dan waktu parsing
Untuk membuat
LocalDateTime
objek dari string, Anda dapat menggunakanLocalDateTime.parse()
metode statis . Dibutuhkan string danDateTimeFormatter
sebagai parameter. IniDateTimeFormatter
digunakan untuk menentukan pola tanggal / waktu.Memformat tanggal dan waktu
Untuk membuat string yang diformat keluar dari
LocalDateTime
objek Anda dapat menggunakanformat()
metode ini.Perhatikan bahwa ada beberapa format tanggal / waktu yang umum digunakan sebagai konstanta dalam
DateTimeFormatter
. Sebagai contoh: MenggunakanDateTimeFormatter.ISO_DATE_TIME
untuk memformatLocalDateTime
instance dari atas akan menghasilkan string"1986-04-08T12:30:00"
.Metode
parse()
danformat()
tersedia untuk semua objek terkait tanggal / waktu (misalnyaLocalDate
atauZonedDateTime
)sumber
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
format()
kelas LocalDateTime alih-alih pada contoh? Setidaknya, itulah yang saya lakukan: Saya bingungDateTime
dengandateTime
contoh di atas.Anda juga dapat menggunakan
LocalDate.parse()
atauLocalDateTime.parse()
padaString
tanpa memberikan dengan pola, jikaString
dalam ISO-8601 Format .sebagai contoh,
Keluaran ,
dan gunakan
DateTimeFormatter
hanya jika Anda harus berurusan dengan pola tanggal lainnya.Misalnya, dalam contoh berikut, dd MMM uuuu mewakili hari dalam sebulan (dua digit), tiga huruf dari nama bulan (Jan, Feb, Mar, ...), dan tahun empat digit:
Keluaran
juga ingat bahwa
DateTimeFormatter
objeknya adalah dua arah; keduanya dapat mengurai input dan memformat output.Keluaran
(lihat daftar lengkap Pola untuk Memformat dan Memilah DateFormatter )
sumber
2018-08-09 12:00:08
tetapi ketika saya menguraikan saya melihatT
ditambahkan yang saya tidak perlu. Apakah ada cara untuk melakukannya ?yyyy-MM-dd hh:mm:ss
untuk parsing dan format. T akan selalu ditampilkan dalam format default (ISO-8061), tetapi Anda dapat menggunakan pola Anda sendiri.Kedua jawaban di atas menjelaskan dengan sangat baik pertanyaan tentang pola string. Namun, untuk berjaga-jaga jika Anda bekerja dengan ISO 8601 tidak perlu diterapkan
DateTimeFormatter
karena LocalDateTime sudah siap untuk itu:Konversi LocalDateTime ke Zona Waktu String ISO8601
Konversi dari ISO8601 String kembali ke LocalDateTime
sumber
Parsing string dengan tanggal dan waktu ke titik waktu tertentu (Java menyebutnya "
Instant
") cukup rumit. Java telah menangani ini dalam beberapa iterasi. Yang terbaru,java.time
danjava.time.chrono
, mencakup hampir semua kebutuhan (kecuali Pelebaran Waktu :)).Namun, kerumitan itu membawa banyak kebingungan.
Kunci untuk memahami penguraian tanggal adalah:
Mengapa Java memiliki banyak cara untuk menguraikan tanggal
... dan mengapa
LocalDateTime
,ZonedDateTime
et al. sangat rumitAda zona waktu . Zona waktu pada dasarnya adalah "garis" * [1] dari permukaan bumi yang otoritasnya mengikuti aturan yang sama tentang kapan zona waktu itu diimbangi. Ini termasuk aturan waktu musim panas.
Zona waktu berubah dari waktu ke waktu untuk berbagai area, sebagian besar didasarkan pada siapa yang menaklukkan siapa. Dan aturan satu zona waktu juga berubah seiring waktu .
Ada offset waktu. Itu tidak sama dengan zona waktu, karena zona waktu mungkin misalnya "Praha", tetapi memiliki offset waktu musim panas dan waktu musim dingin.
Jika Anda mendapatkan stempel waktu dengan zona waktu, offset dapat bervariasi, tergantung pada bagian tahun apa yang digunakan. Selama jam kabisat, stempel waktu dapat berarti 2 waktu yang berbeda, jadi tanpa informasi tambahan, itu tidak dapat diandalkan. dikonversi.
Catatan: Dengan timestamp yang saya maksud "string yang berisi tanggal dan / atau waktu, opsional dengan zona waktu dan / atau offset waktu."
Beberapa zona waktu dapat berbagi offset waktu yang sama untuk periode tertentu. Misalnya, zona waktu GMT / UTC sama dengan zona waktu "London" ketika offset waktu musim panas tidak berlaku.
Untuk membuatnya sedikit lebih rumit (tapi itu tidak terlalu penting untuk kasus penggunaan Anda):
2040-12-31 24:00:00
mungkin tanggal-waktu yang valid.) Ini membutuhkan pembaruan rutin metadata yang digunakan sistem agar konversi tanggal tepat. Misalnya di Linux, Anda mendapatkan pembaruan rutin ke paket Java termasuk data baru ini.Pembaruan tidak selalu menjaga perilaku sebelumnya untuk cap waktu historis dan masa depan. Jadi mungkin terjadi penguraian dua stempel waktu di sekitar perubahan zona waktu yang membandingkannya mungkin memberikan hasil yang berbeda saat dijalankan pada versi perangkat lunak yang berbeda. Itu juga berlaku untuk membandingkan antara zona waktu yang terpengaruh dan zona waktu lainnya.
Jika ini menyebabkan bug pada perangkat lunak Anda, pertimbangkan untuk menggunakan beberapa stempel waktu yang tidak memiliki aturan yang rumit, seperti stempel waktu UNIX .
Karena 7, untuk tanggal mendatang, kami tidak dapat mengonversi tanggal dengan pasti. Jadi, misalnya, penguraian saat ini
8524-02-17 12:00:00
mungkin tidak aktif beberapa detik dari penguraian masa depan.API JDK untuk ini berkembang dengan kebutuhan kontemporer
java.util.Date
memiliki pendekatan yang agak naif, dengan asumsi bahwa hanya ada tahun, bulan, hari, dan waktu. Ini dengan cepat tidak cukup.java.sql.Date
diperkenalkan, dengan keterbatasan sendiri.Calendar
API diperkenalkan.Bagaimana menghadapinya di Jawa
java.time
Tentukan jenis yang akan diurai timestamp untuk
Saat Anda menggunakan string cap waktu, Anda perlu mengetahui informasi apa yang dikandungnya. Ini adalah poin krusial. Jika Anda tidak melakukan ini dengan benar, Anda berakhir dengan pengecualian samar seperti "Tidak dapat membuat Instan" atau "Zona offset hilang" atau "id zona tidak dikenal" dll.
Apakah ini berisi tanggal dan waktu?
Apakah ada offset waktu?
Offset waktu adalah
+hh:mm
bagiannya. Kadang-kadang,+00:00
dapat diganti denganZ
'Zulu time',UTC
sebagai Universal Time Coordinated, atauGMT
sebagai Greenwich Mean Time. Ini juga mengatur zona waktu.Untuk cap waktu ini, Anda gunakan
OffsetDateTime
.Apakah ada zona waktu?
Untuk cap waktu ini, Anda gunakan
ZonedDateTime
.Zona ditentukan baik oleh
Daftar zona waktu dikompilasi oleh "database TZ" , didukung oleh ICAAN.
Menurut
ZoneId
javadoc, id zona juga dapat ditentukanZ
dan diimbangi. Saya tidak yakin bagaimana ini memetakan ke zona nyata. Jika cap waktu, yang hanya memiliki TZ, jatuh ke dalam lompatan waktu dari perubahan offset, maka itu ambigu, dan interpretasinya adalah subjekResolverStyle
, lihat di bawah.Jika tidak ada , maka konteks yang hilang diasumsikan atau diabaikan. Dan konsumen harus memutuskan. Jadi itu perlu diurai
LocalDateTime
dan dikonversiOffsetDateTime
dengan menambahkan info yang hilang:Duration
), atau ketika Anda tidak tahu dan itu tidak masalah (misalnya jadwal bus lokal).Informasi waktu parsial
LocalDate
,LocalTime
,OffsetTime
,MonthDay
,Year
, atauYearMonth
keluar dari itu.Jika Anda memiliki informasi lengkap, Anda bisa mendapatkan
java.time.Instant
. Ini juga digunakan secara internal untuk mengkonversi antaraOffsetDateTime
danZonedDateTime
.Cari tahu bagaimana cara menguraikannya
Ada dokumentasi yang luas
DateTimeFormatter
yang dapat mengurai string stempel waktu dan memformat ke string.The pre-diciptakan
DateTimeFormatter
s harus mencakup moreless semua format timestamp standar. MisalnyaISO_INSTANT
bisa parse2011-12-03T10:15:30.123457Z
.Jika Anda memiliki beberapa format khusus, maka Anda dapat membuat DateTimeFormatter Anda sendiri (yang juga merupakan parser).
Saya merekomendasikan untuk melihat kode sumber
DateTimeFormatter
dan mendapatkan inspirasi tentang cara membangunnya menggunakanDateTimeFormatterBuilder
. Saat Anda berada di sana, lihat jugaResolverStyle
yang mengontrol apakah parser itu LENIENT, SMART, atau STRICT untuk format dan informasi yang ambigu.TemporalAccessor
Sekarang, kesalahan yang sering terjadi adalah masuk ke kompleksitas
TemporalAccessor
. Ini berasal dari bagaimana para pengembang dulu bekerja denganSimpleDateFormatter.parse(String)
. Benar,DateTimeFormatter.parse("...")
memberimuTemporalAccessor
.Tetapi, dilengkapi dengan pengetahuan dari bagian sebelumnya, Anda dapat dengan mudah menguraikan ke dalam jenis yang Anda butuhkan:
Anda sebenarnya tidak perlu ke
DateTimeFormatter
keduanya. Tipe yang ingin Anda parse memilikiparse(String)
metode.Mengenai
TemporalAccessor
, Anda dapat menggunakannya jika Anda memiliki gagasan yang tidak jelas tentang informasi apa yang ada di string, dan ingin memutuskan saat runtime.Saya harap saya memberi sedikit pengertian pada jiwa Anda :)
Catatan: Ada backport
java.time
ke Java 6 dan 7: ThreeTen-Backport . Untuk Android memiliki ThreeTenABP .[1] Tidak hanya itu bukan garis-garis, tetapi ada juga beberapa ekstrem aneh. Misalnya, beberapa pulau pasifik yang berdekatan memiliki zona waktu +14: 00 dan -11: 00. Itu berarti, bahwa sementara di satu pulau, ada 1 Mei 3 sore, di pulau lain tidak begitu jauh, itu masih 30 April 12 PM (jika saya menghitung dengan benar :))
sumber
DAPATKAN WAKTU UTC SAAT INI DALAM FORMAT YANG DIBUTUHKAN
sumber
Saya menemukan itu bagus untuk mencakup beberapa varian format waktu tanggal seperti ini:
sumber