tl; dr
... diurai ... dari sebuah String ... zona waktu tidak ditentukan ... Saya ingin menetapkan zona waktu tertentu
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
Tidak Ada Zona Waktu di juDate
Seperti yang dinyatakan dengan jawaban benar lainnya, java.util.Date tidak memiliki zona waktu † . Ini mewakili UTC / GMT (tidak ada offset zona waktu). Sangat membingungkan karena toString
metodenya menerapkan zona waktu default JVM saat membuat representasi String.
Hindari menjodohkan
Untuk alasan ini dan banyak lainnya, Anda harus menghindari menggunakan java.util.Date & .Calendar & java.text.SimpleDateFormat bawaan. Mereka terkenal merepotkan.
Sebagai gantinya gunakan paket java.time yang dibundel dengan Java 8 .
waktu java
Kelas java.time dapat mewakili momen di timeline dalam tiga cara:
- UTC (
Instant
)
- Dengan offset (
OffsetDateTime
dengan ZoneOffset
)
- Dengan zona waktu (
ZonedDateTime
dengan ZoneId
)
Instant
Di java.time , blok pembangun dasar adalah Instant
, sesaat di garis waktu di UTC. Gunakan Instant
objek untuk banyak logika bisnis Anda.
Instant instant = Instant.now();
OffsetDateTime
Terapkan offset-dari-UTC untuk menyesuaikan waktu tempuh jam tertentu dengan suatu daerah .
Terapkan ZoneOffset
untuk mendapatkan OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Lebih baik menerapkan zona waktu , offset, dan aturan untuk menangani anomali seperti Daylight Saving Time (DST) .
Oleskan ZoneId
ke Instant
untuk mendapatkan ZonedDateTime
. Selalu tentukan nama zona waktu yang tepat . Jangan pernah menggunakan 3-4 singkatan seperti EST
atau IST
yang tidak unik atau standar.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Jika string input tidak memiliki indikator offset atau zona, parsing sebagai a LocalDateTime
.
Jika Anda yakin dengan zona waktu yang dimaksud, tetapkan a ZoneId
untuk menghasilkan a ZonedDateTime
. Lihat contoh kode di atas di bagian dr di atas.
String Terformat
Panggil toString
metode pada salah satu dari tiga kelas ini untuk menghasilkan String yang mewakili nilai tanggal-waktu dalam format standar ISO 8601 . The ZonedDateTime
kelas meluas format standar dengan menambahkan nama zona waktu dalam tanda kurung.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
Untuk format lain gunakan DateTimeFormatter
kelas. Umumnya terbaik untuk membiarkan kelas itu menghasilkan format lokal menggunakan bahasa manusia yang diharapkan dan norma-norma budaya. Atau Anda dapat menentukan format tertentu.
Tentang java.time
The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date
, Calendar
, & SimpleDateFormat
.
Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .
Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu untuk java.sql.*
kelas.
Di mana mendapatkan kelas java.time?
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval
, YearWeek
, YearQuarter
, dan lebih .
Joda-Time
Sementara Joda-Time masih dipelihara secara aktif, pembuatnya telah memberitahu kami untuk bermigrasi ke java.time sesegera mungkin. Saya membiarkan bagian ini tetap utuh sebagai referensi, tetapi saya sarankan menggunakan java.time
bagian di atas sebagai gantinya.
Dalam Joda-Time , objek tanggal-waktu ( DateTime
) benar-benar mengetahui zona waktu yang ditentukan. Itu berarti offset dari UTC dan aturan serta riwayat Daylight Saving Time (DST) zona waktu itu dan anomali lainnya.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Panggil toString
metode untuk menghasilkan String dalam format ISO 8601 .
String output = dateTimeIndia.toString();
Joda-Time juga menawarkan kemampuan yang kaya untuk menghasilkan semua jenis format String lainnya.
Jika diperlukan, Anda dapat mengonversi dari Joda-Time DateTime ke java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Cari StackOverflow untuk "joda date" untuk menemukan lebih banyak contoh, beberapa cukup detail.
† Sebenarnya ada adalah zona waktu tertanam dalam java.util.Date, digunakan untuk beberapa fungsi internal (lihat komentar pada Jawaban ini). Tetapi zona waktu internal ini tidak terekspos sebagai properti, dan tidak dapat ditetapkan. Zona waktu internal ini bukan yang digunakan oleh toString
metode dalam menghasilkan representasi string dari nilai tanggal-waktu; alih-alih zona waktu default JVM saat ini diterapkan saat itu juga. Jadi, sebagai steno, kita sering mengatakan "juDate tidak memiliki zona waktu". Membingungkan? Iya. Namun alasan lain untuk menghindari kelas lama yang lelah ini.