CodeGym /Java Blog /Acak /Bagaimana tidak tersesat dalam waktu: DateTime dan Calend...
John Squirrels
Level 41
San Francisco

Bagaimana tidak tersesat dalam waktu: DateTime dan Calendar

Dipublikasikan di grup Acak
Hai! Hari ini kita akan mulai bekerja dengan tipe data baru yang belum pernah kita temui sebelumnya, yaitu tanggal. Bagaimana tidak tersesat dalam waktu: DateTime and Calendar - 1Saya rasa saya tidak perlu menjelaskan apa itu kencan. :) Pada prinsipnya, kita dapat menyimpan tanggal dan waktu saat ini dalam Java String biasa.

public class Main {
   public static void main(String[] args) {

       String date = "June 11, 2018";
       System.out.println(date);
   }
}
Tetapi pendekatan ini memiliki banyak kelemahan. Kelas Stringdirancang untuk bekerja dengan teks, dan metodenya sesuai untuk tugas ini. Jika kita perlu memanipulasi tanggal dengan cara tertentu (menambahkan 2 jam, misalnya), Stringtidak bekerja dengan baik. Atau jika kita ingin menampilkan tanggal dan waktu saat program dikompilasi. Stringtidak membantu di sini juga: pada saat Anda menulis kode dan menjalankannya, waktunya akan berubah dan konsol akan menampilkan informasi yang salah. Itu sebabnya pencipta Java menyediakan beberapa kelas untuk bekerja dengan tanggal dan waktu. Yang pertama adalahjava.util.Date

Kelas tanggal

Kami menentukan nama lengkapnya, karena paket Java lain memiliki class java.sql.Date. Jangan campur mereka! Hal pertama yang perlu Anda ketahui tentang itu adalah ia menyimpan tanggal sebagai jumlah milidetik yang telah berlalu sejak 1 Januari 1970. Sistem waktu ini bahkan memiliki namanya sendiri: " Unix-time " Pendekatan yang agak menarik, bukan? apakah kamu setuju? :) Hal kedua yang perlu diingat adalah ini: Jika Anda membuat Dateobjek menggunakan konstruktor default, hasilnya mewakili tanggal dan waktu saat ini saat objek dibuat . Ingat bahwa kami mengatakan bahwa tanggal yang direpresentasikan sebagai Stringakan berjuang dengan tugas seperti itu? Kelas Datemenanganinya dengan mudah.

public class Main {
   public static void main(String[] args) {

       Date date = new Date();
       System.out.println(date);
   }
}
Jalankan kode ini beberapa kali, dan Anda akan melihat waktu berubah berulang kali. :) Ini dimungkinkan karena waktu disimpan sebagai milidetik: satuan waktu yang sangat kecil, sehingga hasilnya sangat akurat. Kelas Datekonstruktor lain: Anda dapat meneruskan jumlah persis milidetik sejak 00:00 pada 1 Januari 1970 ke tanggal yang diperlukan, dan objek tanggal yang sesuai akan dibuat:

public class Main {
   public static void main(String[] args) {

       Date date = new Date(1212121212121L);
       System.out.println(date);
   }
}
Keluaran konsol: Jum 30 Mei 04:20:12 GMT 2008 Kami mendapatkan 30 Mei 2008. "Jumat" menunjukkan hari dalam seminggu (Jumat, duh), dan GMT adalah zona waktu (Greenwich Mean Time). Milidetik dilewatkan sebagai longs, karena jumlah milidetik biasanya tidak sesuai dengan int. Jadi, operasi apa dengan tanggal yang mungkin perlu kita lakukan? Nah, yang paling jelas tentunya adalah perbandingan . Untuk menentukan apakah satu tanggal datang sebelum atau setelah yang lain. Hal ini dapat dilakukan dengan beberapa cara. Misalnya, Anda dapat memanggil Date.getTime()metode yang mengembalikan jumlah milidetik yang telah berlalu sejak tengah malam pada tanggal 1 Januari 1970. Cukup panggil pada dua objek Tanggal dan bandingkan hasilnya:

public class Main {
   public static void main(String[] args) {

       Date date1 = new Date();

       Date date2 = new Date();

       System.out.println((date1.getTime() > date2.getTime())?
               "date1 is later than date2" : "date1 is earlier than date2");
   }
}
Keluaran: date1 lebih awal dari date2 Namun ada juga cara yang lebih mudah, yaitu dengan menggunakan metode khusus yang disediakan oleh kelas Date: before(), after()dan equals(). Semuanya mengembalikan nilai boolean. Metode before()memeriksa apakah tanggal kita lebih awal dari tanggal yang diteruskan sebagai argumen:

public class Main {
   public static void main(String[] args) throws InterruptedException {

       Date date1 = new Date();

       Thread.sleep(2000);// Suspend the program for 2 seconds
       Date date2 = new Date();

       System.out.println(date1.before(date2));
   }
}
Keluaran konsol: benar Demikian pula, after()metode memeriksa untuk melihat apakah tanggal kita lebih lambat dari tanggal yang diteruskan sebagai argumen:

public class Main {
   public static void main(String[] args) throws InterruptedException {

       Date date1 = new Date();

       Thread.sleep(2000);// Suspend the program for 2 seconds
       Date date2 = new Date();

       System.out.println(date1.after(date2));
   }
}
Keluaran konsol: salah Dalam contoh kami, kami "menidurkan program" selama 2 detik, sehingga kedua tanggal dijamin berbeda. Pada komputer cepat, waktu antara pembuatan date1dan date2bisa kurang dari satu milidetik, menyebabkan keduanya before()dan after()kembali salah. Tetapi dalam kasus ini, equals()metode akan kembali benar! Lagi pula, ini membandingkan jumlah milidetik sejak 00:00 pada 1 Januari 1970 untuk setiap tanggal. Objek dianggap sama hanya jika cocok dengan milidetik :

public static void main(String[] args) {

   Date date1 = new Date();
   Date date2 = new Date();

   System.out.println(date1.getTime());
   System.out.println(date2.getTime());

   System.out.println(date1.equals(date2));
}
Inilah hal lain yang perlu Anda perhatikan. Jika Anda membuka dokumentasi untuk Datekelas tersebut di situs web Oracle , Anda akan melihat bahwa banyak metode dan konstruktornya telah ditandai sebagai Usang (tidak direkomendasikan untuk digunakan). Inilah yang dikatakan pembuat Java tentang bagian kelas yang telah ditinggalkan:
"Elemen program yang dianotasi @Deprecated adalah sesuatu yang tidak disarankan untuk digunakan oleh pemrogram, biasanya karena berbahaya, atau karena ada alternatif yang lebih baik."
Ini tidak berarti bahwa metode ini tidak dapat digunakan sama sekali. Jika Anda mencoba menjalankan kode menggunakan metode usang dalam IDE, kemungkinan besar itu akan berhasil. Misalnya, pertimbangkan metode usang Date.getHours(), yang mengembalikan jumlah jam yang terkait dengan Dateobjek.

public static void main(String[] args) {

   Date date1 = new Date();

   System.out.println(date1.getHours());
}
Jika Anda memulai kode pada 14:21 (14:21), itu akan menampilkan angka 14. Seperti yang Anda lihat, metode usang dicoret, tetapi masih berfungsi. Metode-metode ini tidak dihapus agar tidak merusak sebagian besar kode yang ada yang menggunakannya. Dengan kata lain, metode ini tidak "rusak" atau "dihapus". Mereka tidak direkomendasikan untuk digunakan karena tersedia alternatif yang lebih nyaman. Kebetulan, dokumentasi secara khusus menyebutkan alternatif ini:
Bagaimana tidak tersesat dalam waktu: DateTime and Calendar - 2
Sebagian besar Datemetode kelas telah dipindahkan ke Calendarkelas yang ditingkatkan dan diperluas. Kita akan berkenalan dengan kelas itu selanjutnya. :)

Kelas kalender

JDK 1.1 memperkenalkan kelas baru: Calendar. Itu membuat bekerja dengan tanggal di Jawa agak lebih mudah dari sebelumnya. Satu-satunya implementasi kelas Calendaryang akan kita kerjakan adalah kelasnya GregorianCalendar. Ini menerapkan kalender Gregorian, yang diamati oleh sebagian besar negara di dunia. Keuntungan utamanya adalah dapat bekerja dengan tanggal dalam format yang lebih nyaman. Misalnya, ini dapat:
  • Tambahkan bulan atau hari ke tanggal saat ini
  • Periksa apakah tahun tersebut merupakan tahun kabisat;
  • Kembalikan masing-masing komponen tanggal (misalnya, ekstrak nomor bulan dari seluruh tanggal)
  • Ini juga berisi sistem konstanta yang sangat nyaman (banyak di antaranya akan kita lihat di bawah).
Peningkatan penting lainnya dari Calendarkelas adalah konstanta Calendar.ERA : Anda dapat menunjukkan tanggal sebelum era umum (BC - sebelum Kristus) atau di era umum (AD - Anno Domini). Mari kita lihat semua ini dengan contoh. Mari buat calendarobjek dengan tanggal 25 Januari 2017:

public static void main(String[] args) {

  Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
Di Calendarkelas (serta Datekelas dalam hal ini), bulan dimulai dari nol , jadi kami meneruskan angka 0 sebagai argumen kedua. Saat bekerja dengan Calendarkelas, penting untuk dipahami bahwa ini hanya kalender , bukan tanggal individual. Bagaimana tidak tersesat dalam waktu: DateTime and Calendar - 3 Tanggal hanyalah beberapa angka yang menunjukkan interval waktu tertentu. Kalender adalah keseluruhan sistem yang memungkinkan Anda melakukan banyak hal dengan tanggal. :) Ini sangat jelas jika Anda mencoba menampilkan Calendarobjek: Keluaran: java.util.GregorianCalendar[waktu=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Eropa/London",offset=0,dstSavings=0,useDaylight= false,transitions=79,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=1,ERA=?,YEAR=2017,MONTH=0,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=25,DAY_OF_YEAR=?,DAY_OF_WEEK=? ,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?] Lihat berapa banyak informasi yang Anda dapatkan ! Kalender memiliki banyak properti yang tidak dimiliki oleh tanggal normal, dan semuanya ditampilkan (begitulah caratoString()kerja metode diCalendarkelas). Jika Anda hanya perlu mendapatkan tanggal sederhana dari kalender, misalnya objekDate, gunakan theCalendar.getTime()metode (namanya bukan yang paling logis, tapi apa yang bisa Anda lakukan?):

public static void main(String[] args) {

   Calendar calendar = new GregorianCalendar(2017, 0 , 25);
   Date date = calendar.getTime();
   System.out.println(date);
}
Keluaran: Rab 25 Jan 00:00:00 GMT 2017 Sekarang kami telah mengambil kalender dan "menguranginya" menjadi tanggal biasa. Mari melangkah lebih jauh. Selain menentukan bulan berdasarkan jumlahnya, Anda dapat menggunakan nilai bidang konstantaCalendar kelas . Konstanta ini adalah bidang statis kelas dengan nilai prasetel yang tidak dapat diubah. Ini sebenarnya adalah opsi yang lebih baik, karena menggunakannya meningkatkan keterbacaan kode Anda. Calendar

public static void main(String[] args) {
   GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Calendar.JANUARY adalah salah satu konstanta yang mewakili bulan dalam setahun. Dengan menggunakan konstanta bernama ini, tidak ada yang akan lupa, misalnya, bahwa angka 3 berarti April, dan bukan bulan ketiga, yang biasa kita sebut Maret. Cukup tulis Calendar.APRIL , dan selesai. :) Semua bidang kalender (angka, bulan, menit, detik, dll.) dapat ditentukan secara terpisah menggunakanset()metode ini. Metode ini sangat nyaman, karenaCalendarkelas memiliki konstanta untuk setiap bidang, dan kode yang dihasilkan sangat mudah dibaca. Pada contoh terakhir, kami membuat tanggal, tetapi tidak menetapkan waktu untuk itu. Mari atur waktu 19:42:12

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar();
   calendar.set(Calendar.YEAR, 2017);
   calendar.set(Calendar.MONTH, 0);
   calendar.set(Calendar.DAY_OF_MONTH, 25);
   calendar.set(Calendar.HOUR_OF_DAY, 19);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   System.out.println(calendar.getTime());
}
Keluaran: Rab 25 Jan 19:42:12 GMT 2017 Kami memanggil set()metode, meneruskan konstanta (tergantung pada bidang yang ingin kami ubah) dan nilai baru untuk bidang tersebut. Ternyata set()metode ini adalah semacam "penyetel super" yang tahu cara menetapkan nilai tidak hanya untuk satu bidang, tetapi untuk banyak bidang. :) CalendarKelas menggunakan add()metode untuk menambah dan mengurangi nilai. Anda memasukkan bidang yang ingin Anda ubah, dan angka (persis berapa banyak yang ingin Anda tambahkan/kurangi dari nilai saat ini). Misalnya, mari dapatkan tanggal 2 bulan sebelum tanggal yang kita buat:

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 19);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.add(Calendar.MONTH, -2); // To subtract, pass a negative number
   System.out.println(calendar.getTime());
}
Keluaran: Jum 25 Nov 19:42:12 GMT 2016 Sangat bagus! Kami mendapat tanggal 2 bulan yang lalu. Ini tidak hanya menyebabkan bulan berubah: tahun juga berubah dari 2017 ke 2016. Tentu saja, saat mengonversi tanggal, tahun saat ini dihitung secara otomatis tanpa perlu Anda melacaknya secara manual. Tetapi jika karena alasan tertentu Anda perlu menonaktifkan perilaku ini, Anda dapat melakukannya. Metode ini roll()dapat menambah dan mengurangi nilai tanpa mempengaruhi nilai yang tersisa . Misalnya, seperti ini:

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.roll(Calendar.MONTH, -2);
   System.out.println(calendar.getTime());
}
Kami melakukan hal yang persis sama seperti pada contoh sebelumnya: kami mengambil 2 bulan dari tanggal saat ini. Tapi sekarang kodenya melakukan sesuatu yang berbeda: bulan telah berubah dari Januari hingga November, tetapi tahun tetap tidak berubah—2017! Keluaran: Sabtu 25 Nov 10:42:12 GMT 2017 Bergerak bersama. Seperti yang kami katakan di atas, kami bisa mendapatkan semua Calendarbidang secara terpisah. Kami melakukan ini dengan get()metode:

public static void main(String[] args) {
   GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   System.out.println("Year: " + calendar.get(Calendar.YEAR));
   System.out.println("Month: " + calendar.get(Calendar.MONTH));
   System.out.println("Week in the month: " + calendar.get(Calendar.WEEK_OF_MONTH));// Week in this month?

   System.out.println("Day: " + calendar.get(Calendar.DAY_OF_MONTH));

   System.out.println("Hours: " + calendar.get(Calendar.HOUR));
   System.out.println("Minutes: " + calendar.get(Calendar.MINUTE));
   System.out.println("Seconds: " + calendar.get(Calendar.SECOND));
   System.out.println("Milliseconds: " + calendar.get(Calendar.MILLISECOND));

}
Keluaran: Tahun: 2017 Bulan: 0 Minggu dalam sebulan: 5 Hari: 25 Jam: 10 Menit: 42 Detik: 12 Milidetik: 0 Jadi, selain kelas Calendar"super-setter", ada juga "super-getter" ". :) Tentu saja, aspek lain yang menarik dari kelas ini adalah bekerja dengan era. Untuk membuat tanggal "BC", Anda harus menggunakan kolom Calendar.ERA Misalnya, mari buat tanggal untuk Pertempuran Cannae, saat Hannibal mengalahkan tentara Romawi. Ini terjadi pada 2 Agustus 216 SM:

public static void main(String[] args) {
   GregorianCalendar cannae = new GregorianCalendar(216, Calendar.AUGUST, 2);
   cannae.set(Calendar.ERA, GregorianCalendar.BC);

   DateFormat df = new SimpleDateFormat("MMM dd, yyy GG");
   System.out.println(df.format(cannae.getTime()));
}
Di sini kami menggunakan SimpleDateFormatkelas untuk mencetak tanggal dalam format yang lebih mudah untuk kami pahami (huruf "GG" menunjukkan kami ingin menampilkan era). Keluaran: 02 Agustus 216 SM. Kelas Calendarmemiliki lebih banyak metode dan konstanta. Anda dapat membacanya di dokumentasi . Jika tidak menyukai format tanggal ini Sabtu 25 Nov 10:42:12 GMT 2017 maka Anda dapat menggunakan SimpleDateFormatuntuk membuatnya dengan mudah seperti yang Anda inginkan.

public static void main(String[] args) {

   SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.roll(Calendar.MONTH, -2);
   System.out.println(dateFormat.format(calendar.getTime()));
}
Keluaran : Sabtu, 25 November 2017 Jauh lebih baik bukan? :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION