• Tidak ada hasil yang ditemukan

Joda Time

Dalam dokumen c2ed0 java desktop ifnu bima (Halaman 94-100)

} }

Hasil eksekusinya adalah seperti berikut : $ javac SimpleDateFormatTest.java $ java SimpleDateFormatTest 16/02/2011 01:32:26

21 December 1990 $

Manipulasi tanggal menggunakan Calendar dan memformat tanggal menggunakan SimpleDateFormat terkadang memerlukan kode yang cukup panjang dan tidak praktis. Masalah kurang handalnya library pengolahan tanggal yang ada dalam JDK sudah banyak diketahui, di JDK 7 nanti akan ada library tanggal yang baru di JSR-310. library ini diturunkan dari library tanggal yang sangat populer dan powerfull, yaitu Joda Time. Di bab berikutnya kita akan membandingkan bagaimana mengolah data menggunakan Calendar vs menggunakan Joda Time.

Joda Time

Joda Time adalah library pengolahan tanggal yang ditulis oleh Stephen Colebourne karena sudah cukup frustasi dengan library pengolahan tanggal di dalam JDK yang cukup merepotkan untuk perhitungan tanggal yang rumit. API untuk pengolahan tanggal bisa dibilang sebagai API yang paling buruk dalam JDK saat ini. API tanggal mulai ada semenjak JDK versi 1.0, James Gosling mencontek implementasi tanggal dari C, dimana implementasinya masih sederhana dan memiliki banyak kelemahan secara design. Misalnya bulan di dalam class Date dimulai dari 0 hingga 11, jadi kalau kita panggil method getMonth dari class Date untuk bulan Desember maka nilainya adalah 11, bukan 12. Joda Time dibuat untuk memperbaiki hal ini.

Selain itu Joda Time juga mengenalkan beberapa konsep baru, seperti periode, interval dan implementasi daerah waktu (timezone) yang lebih baik. Feature chronology juga sangat membantu kalau kita ingin bekerja dengan sistem penanggalan yang tidak umum digunakan, seperti penanggalan islam, budha, julian dan sebagainya.

Joda Time bisa digunakan bersamaan dengan class Date dan Calendar dengan baik, kita bisa melakukan konversi dari class-class Joda Time menjadi kedua class tersebut dengan mudah. Jadi Joda Time digunakan sebagai library perhitungan tanggal yang bisa melakukan hal-hal rumit

dengan mudah, kemudian setelah selesai peroses perhitunganya kita bisa mendapatkan hasilnya dalam bentuk class Date. Feature backward compatibility inilah salah satu daya tarik dari Joda Time.

Sebelum kita mulai belajar tentang konsep dalam Joda Time, kita perlu mendownload library Joda Time dari alamat di bawah ini :

http://sourceforge.net/projects/joda-time/fles/joda-time/

pada saat buku ini ditulis versi yang terbaru adalah 1.6.2, kita hanya perlu satu buah jar saja yaitu joda-time.1.6.2.jar.

Joda Time memperkenalkan enam konsep waktu, yaitu :

• Instant : sebuah instant adalah nilai dalam mili detik dari 1 januari 1970 00:00:00 hingga sekarang.

• Parsial : representasi sebagian dari waktu, misalnya tanggal saja atau waktu saja.

• Interval : interval waktu dari awal hingga akhir. Dalam interval terdapat dua buah instant yaitu awal dan akhir.

• Durasi : durasi waktu dalam mili detik, misalnya 1000 mili detik.

• Periode : periode waktu yang direpresentasikan dalam satuan-satuan waktu, misalnya 1 hari 2 jam 3 menit dan 30 detik.

• Chronology : sistem penanggalan yang bisa digunakan sebagai basis perhitungan waktu. Class-class implementasi dari setiap konsep di atas adalah sebagai berikut :

Konsep Class Immutable Class Mutable

Instant Instant, DateTime, DateMidnight MutableDateTime

Parsial LocalDate, LocalTime,

LocalDateTime,Partial

Interval Interval MutableInterval

Periode Period, Minutes, Hours, Days, Weeks, Months, Years

MutablePeriod Durasi Duration Chronology GregorianChronology, ISOChronology (default), BuddhistChronology, JulianChronology, EthiopicChronology, CopticChronology, GJChronology

Mari kita bahas satu per satu konsep di atas dengan disertai contoh kode untuk mempermudah pemahaman terhadap konsep-konsep dalam Joda Time.

Instant adalah konsep paling sederhana, konsep ini sama dengan class Date, yaitu representasi jumlah mili detik dari tanggal 1 januari 1970 00:00:00 hingga sekarang. Joda Time mempunyai beberapa class yang digunakan untuk merepresentasikan instant ini, dua class yang sering digunakan adalah class Instant dan class DateTime. Class Instant berisi satu buah property dalam mili detik, perhatikan contoh berikut ini untuk memahami class Instant :

import org.joda.time.Instant; public class InstantTest {

public static void main(String[] args) {

Instant instant = new Instant(1000); // 1 detik setelah 1970 //ingat bahwa instant mutable sehingga perlu diset lagi setelah //diubah nilainya

instant = instant.plus(100); //ditambah 100 milidetik instant = instant.plus(60000); //ditambah satu menit System.out.println(instant);

}

Untuk mengcompile kode di atas, kita perlu menambahkan jar Joda Time ke dalam classpath. Letakkan joda-time.1.6.2.jar ke dalam folder yang sama dengan fle java dari class di atas, kemudian jalankan command di bawah ini untuk mengcompile dan menjalankan kode di atas. Jalankan perintah di bawah ini kalau anda bekerja dengan Linux, Unix dan Mac :

$ javac -cp joda-time-1.6.2.jar InstantTest.java $ java -cp joda-time-1.6.2.jar:. InstantTest 1970-01-01T00:01:01.100Z

$

Sedangkan untuk Windows perintahnya sedikit berbeda, hal ini dikarenakan perbedaan pemisah classpath, dimana untuk Linux/Unix/Mac menggunakan : (titik dua) dan windows menggunakan ; (titik koma) :

$ javac -cp joda-time-1.6.2.jar InstantTest.java $ java -cp joda-time-1.6.2.jar;. InstantTest 1970-01-01T00:01:01.100Z

$

Class DateTime juga merepresentasikan konsep Instant. Class ini fungsinya menggabungkan fungsi dalam class Date plus class Calender, karena bisa digunakan sebagai representasi waktu sekaligus mempunyai method-method untuk melakukan manipulasi data waktu. Berikut ini adalah contoh penggunaan class DateTime :

import org.joda.time.DateTime; import java.util.Date;

import java.util.Calendar; public class DateTimeTest {

public static void main(String[] args) {

DateTime dateTime = new DateTime(); //waktu sekarang int date = dateTime.getDayOfMonth();

int month = dateTime.getMonthOfYear(); //dimulai dari 1 hingga 12 int year = dateTime.getYear();

DateTime plusMonth = dateTime.plusMonths(2); DateTime plusMinutes = dateTime.plusMinutes(2);

Date d = plusMonth.toDate(); //mengubah DateTime ke Date

Calendar c = plusMinutes.toGregorianCalendar(); //mengubah DateTime ke Calendar System.out.println(dateTime);

} }

Partial digunakan untuk merepresentasikan waktu yang terpisah antara tanggal dan jam tanpa daerah waktu (timezone). Misalnya class LocalDate hanya mempunyai property tanggal, bulan dan tahun, sedangkan class LocalTime hanya mempunyai property jam, menit, detik dan mili detik. Class ini jarang digunakan dan lebih praktis menggunakan class DateTime saja untuk representasi waktu, class-class tersebut ada hanya untuk tujuan backward compatibility dengan versi Joda Time yang lebih lama. Contoh kodenya seperti di bawah ini :

import org.joda.time.LocalDate; public class PartialTest {

public static void main(String[] args) {

LocalDate birthDay = new LocalDate(1965,1,23);

long millis = birthDay.toDateTimeAtCurrentTime().getMillis(); System.out.println(millis); //bernilai negatif karena sebelum 1970 birthDay = birthDay.plusYears(27); //ultah ke 27

int year = birthDay.getYear(); //tahun ultah ke 27 }

}

Interval adalah representasi jarak antara satu instant dengan intant yang lainya. Konsep interval mempunyai dua buah instant yaitu waktu mulai dan waktu selesai. Class Interval digunakan untuk

merepresentasikan konsep interval ini. Method getStart dari class Interval digunakan untuk mendapatkan waktu mulai, sedangkan method getEnd digunakan untuk mendapatkan waktu selesai. Kalau ingin mengubah waktu awal gunakan method withStart dan kalau ingin mengubah waktu akhir gunakan method withEnd.

Contoh penggunaan interval adalah sebeagai berikut ini : import org.joda.time.DateTime;

import org.joda.time.Interval; public class IntervalTest {

public static void main(String[] args) { DateTime now = new DateTime();

DateTime oneMonthLater = now.plusMonths(1);

Interval interval = new Interval(now, oneMonthLater); System.out.println("interval : " + interval);

System.out.println("start : " + interval.getStart()); System.out.println("end : " + interval.getEnd());

System.out.println("duration : " + interval.toDuration()); //merubah nilai end interval dengan menambahkan satu jam interval.withEnd(interval.getEnd().plusHours(1));

} }

Kalau kita eksekusi kode di atas, hasilnya adalah seperti di bawah ini : $ javac -cp joda-time-1.6.2.jar IntervalTest.java

$ java -cp joda-time-1.6.2.jar:. IntervalTest

interval : 2011-02-16T03:34:37.877/2011-03-16T03:34:37.877 start : 2011-02-16T03:34:37.877+08:00

end : 2011-03-16T03:34:37.877+08:00 duration : PT2419200S

$

Kalau anda bekerja dengan windows, jangan lupa mengganti pemisah classpath dengan simbil ; (titik koma).

Konsep durasi dalam Joda Time merepresentasikan lama waktu dalam mili detik. Durasi bisa dihitung langsung dengan memasukkan nilai durasi dalam mili detik atau bisa juga dihitung dari sebuah interval. Contoh kode penggunaan durasi seperti di bawah ini :

import org.joda.time.Duration; import org.joda.time.DateTime; public class DurationTest {

public static void main(String[] args) {

Duration duration = new Duration(10000); // 10 detik System.out.println("duration : " + duration);

DateTime now = new DateTime();

DateTime oneMonthLater = now.plusMonths(1); duration = new Duration(now, oneMonthLater);

System.out.println("duration of one month : " + duration); Duration oneHour = new Duration(1000 * 60 * 60);

DateTime oneHourLater = now.plus(oneHour);

System.out.println("one hour later : " + oneHourLater); }

}

Hasil eksekusi kode di atas adalah seperti berikut ini : $ javac -cp joda-time-1.6.2.jar DurationTest.java $ java -cp joda-time-1.6.2.jar:. DurationTest duration : PT10S

duration of one month : PT2419200S

$

Kalau anda bekerja dengan windows, jangan lupa mengganti pemisah classpath dengan simbil ; (titik koma).

Durasi adalah konsep komputer yang ketat, artinya durasi bisa diukur dalam mili detik dan tidak terikat dengan suatu waktu tertentu. Sedangkan periode adalah sebuah konsep durasi yang sedikit berbeda karena terikat dengan suatu waktu tertentu dan lebih condong sebagai intepretasi manusia terhadap waktu dibanding intepretasi mesin terhadap waktu. Contoh periode adalah : 1 tahun 2 bulan 30 hari, nah berapa total lama periode tersebut dalam mili detik tidaklah selalu sama, tergantung dari mana awal dari periode tersebut. Misalnya 1 tahun di tahun 2000 dengan 1 tahun di tahun 2001 akan berbeda dalam satuan mili detik karena tahun 2000 adalah tahun kabisat di penanggalan gregorian.

Di sisi lain, periode ini lebih praktis dibanding dengan durasi, terutama kalau nilainya lumayan tinggi dan didefnisikan dalam pecahan waktu. Berikut ini contoh penggunaan dari konsep periode:

import org.joda.time.Period; import org.joda.time.DateTime; import org.joda.time.Hours; import org.joda.time.Minutes; public class PeriodTest {

public static void main(String[] args) { Period p = new Period(1000); //1 detik System.out.println("period : " + p);

p = new Period(2,3,9,125); //2 jam 3 menit 9 detik dan 125 mili detik System.out.println("period : " + p);

DateTime startTime = new DateTime(2000,1,1,9,0,0,0); //1 januari 2000 jam 9 //menambahkan period ke instant untuk mendapatkan instant baru

DateTime endTime = startTime.plus(p); System.out.println("end time : " + endTime);

//Periode nilainya tidak menentu, satu hari belum tentu 24 jam, //tergantung apakah hari itu ada daylight savings atau tidak. //Begitupula satu tahun belum tentu 365 hari,

//tergantung kabisat atau tidak.

//Mengubah Period ke durasi harus ada waktu awal,

//kemudian ditambah dengan period dapat waktu akhir dan dihitung durasinya Hours hours = Hours.hoursBetween(startTime,endTime);

//mendapatkan durasi dalam jam dengan tipe data int int hoursBetween = hours.getHours();

System.out.println("hours duration : " + hours);

Minutes minutes = Minutes.minutesBetween(startTime, endTime); System.out.println("minutes duration : " + minutes);

} }

Hasil eksekusi kode di atas adalah sebagai berikut : $ javac -cp joda-time-1.6.2.jar PeriodTest.java $ java -cp joda-time-1.6.2.jar:. PeriodTest period : PT1S period : PT2H3M9.125S end time : 2000-01-01T11:03:09.125+08:00 hours duration : PT2H minutes duration : PT123M $

Kalau anda bekerja dengan windows, jangan lupa mengganti pemisah classpath dengan simbil ; (titik koma).

didasarkan pada jenis penanggalan yang digunakan. Joda Time secara default menyediakan beberapa sistem penanggalan, antara lain :

• Gregorian : standard penanggalan masehi yang dimulai pada 15 september 1582, penanggalan ini mendefnisikan bahwa tahun kabisat hanya terjadi pada tahun yang habis dibagi 4, tidak habis dibagi 100 dan habis dibagi 400. Misalnya tahun 2008 adalah kabisat karena habis dibagi 4, tahun 2100 bukan kabisat karena walaupun habis dibagi 4 juga habis dibagi 100. Tahun 2000 adalah kabisat karena habis dibagi 4, walaupun habis dibagi 100 tetapi habis dibagi 400.

• Julian : standard penanggalan masehi yang sebelum tanggal 15 september 1582. Penanggalan ini mendefnisikan bahwa setiap tahun yang habis dibagi 4 adalah tahun kabisat.

• ISO8601 : standard penanggalan yang menggunakan sistem Gregorian plus standarisasi format penulisan tanggal. Joda Time secara default menggunakan ISO8601 sebagai default chronology

• GJ : penanggalan yang menggabungkan Julian dan Gregorian. Sebelum tanggal 15 September 1582 sistem penanggalan yang digunakan adalah Julian dan setelahnya adalah Gregorian.

• Penanggalan lain yang spesifk : Buddhist, Coptic, Ethiopic

Sampai di sini kita sudah belajar secara umum tentang konsep waktu dalam Joda Time beserta implementasinya, nah kita akan membahas lagi sedikit tentang bagaimana Joda Time menyederhanakan kode perhitungan tanggal yang dibuat dengan class dari JDK.

Contoh pertama : membuat instant, tambahkan 20 hari kemudian print hasilnya ke dalam console dengan format tanggal tertentu. Kode untuk melakukan perhitungan tersebut dengan menggunakan class-class dari JDK adalah seperti berikut ini :

import java.util.Calendar;

import java.text.SimpleDateFormat; public class CalculateDateTest {

public static void main(String[] args) { Calendar c = Calendar.getInstance(); c.set(2000,Calendar.JANUARY,1,0,0,0); c.add(Calendar.DATE, 20);

SimpleDateFormat format = new SimpleDateFormat("dd MMM yyyy HH:mm:ss"); System.out.println("date : " + format.format(c.getTime()));

} }

Implementasinya menggunakan Joda Time memerlukan jumlah baris kode setengahnya dari kode di atas :

import org.joda.time.DateTime; public class CalculateDateJodaTest { public static void main(String[] args) { DateTime d = new DateTime(2000,1,1,0,0,0,0); System.out.println("date : " +

d.plusDays(20).toString("dd MMM yyyy HH:mm:ss")); }

}

Contoh kedua sedikit lebih rumit, misalnya kita ingin mengetahui hasil perhitungan ini : tanggal awal adalah 1 januari 2000, tambahkan 1 bulan 45 hari dari tanggal awal, kemudian cari tanggal berapa di hari minggu pada minggu tersebut. Perhitungan ini cukup rumit untuk dibuat implementasinya menggunakan library JDK, tetapi menggunakan Joda Time perhitungan ini sangat sederhana dan hanya memerlukan beberapa baris kode saja. Implementasinya :

import org.joda.time.DateTime;

public static void main(String[] args) { DateTime d = new DateTime(2000,1,1,0,0,0,0); System.out.println("date : " +

d.plusMonths(1).plusDays(45).dayOfWeek()

.withMaximumValue().toString("dd MMM yyyy HH:mm:ss")); }

}

Library Joda Time adalah library yang wajib ada di setiap project yang kita buat. Perhitungan tanggal menjadi mudah menggunakan Joda Time.

Dalam dokumen c2ed0 java desktop ifnu bima (Halaman 94-100)