.::. Hendra Jaya .::.

June 19, 2009

Toleransi Pattern Pada Kelas DateFormat..

Filed under: Java — hjaya @ 10:06 am

Di Java, kita mengenal kelas DateFormat. Kelas ini berfungsi untuk mem-parsing String (dalam pattern tertentu) menjadi Date dan juga sebaliknya.

Secara singkat, kita biasa menggunakan kelas DateFormat seperti ini :

  public class Main {
    public static void
main(String... args) {
      String pattern = "yyyyMMdd";
      DateFormat dateFormatter = new SimpleDateFormat(pattern);
      String _17_Juni_09 = "20090617";

      try {
        System.out.println(dateFormatter.parse(_17_Juni_09));
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
  }

Ada satu hal menarik yang akan kita bahas dalam kode program di atas. Yaitu ParseException. Secara default, DateFormat akan berusaha sebaik-baiknya untuk mem-parsing parameter yang dikirimkan. Hal ini bisa berakibat baik dan bisa juga berakibat buruk. Sebagai best practice, sebaiknya kita mempelajari keburukan dari toleransi dari DateFormat.

Contoh 1 : Sebuah String “20090617″ akan diterjemahkan sebagai 17 Juni 2009 (benar)

Parameter yang dikirim logically dan physically benar. Logically benar karena tanggal 17 Juni 2009 memang benar-benar ‘ada’ dan physically benar karena mengikuti kaedah penulisan tanggal yang benar

Contoh 2 : Sebuah String “20090635″ akan diterjemahkan sebagai 5 Juli 2009 (bisa benar, bisa salah)

Parameter yang dikirim logically salah namun physically benar. Logically salah karena tanggal 35 Juni 2009 sebenarnya tidak ‘ada’ tetapi physically benar karena mengikuti kaedah penulisan tanggal yang benar.

Contoh 3 : Sebuah String “200906a7″ akan menghasilkan ParseException (benar)

Parameter yang dikirim logically salah dan physically salah.

Pada contoh ke-2, mengapa DateFormat tidak melempar exception?? Karena memang secara default, DateFormat akan mentolerir kesalahan logic dan akan tetap berusaha mem-parsing input yang diberikan.

Pada contoh ke-3, mengapa DateFormat melempar exception?? Karena input yang dikirim memang tidak bisa diparsing.

Kesimpulan yang bisa kita tarik sampai saat ini adalah DateFormat secara default hanya akan melempar exception jika data physically salah sehingga proses parsing pasti gagal. Tetapi, bagaimana dengan data yang logically salah?

Secara default, DateFormat akan mentolerir hal ini dan dengan senang hati mencoba ‘membenarkan’ input yang diterima. Pada contoh di atas, tanggal 35 Juni 2009 akan diterjemahkan menjadi 5 Juli 2009. Hal inilah yang bisa berakibat baik dan juga bisa berakibat buruk. Berakibat baik kalau programmer sudah mengerti akan perilaku ini dan memang sengaja membiarkan DateFormat melakukannya.

Tetapi, kebanyakan coder (bukan programmer) akan terjebak dengan feature ini dan mengira bahwa input yang dikirim tidak bermasalah dan aplikasi berjalan baik-baik saja. Well, memang benar bahwa aplikasi berjalan baik-baik saja… tetapi ketidak-aware-an para coder akan berakibat fatal pada Business Process.

Contoh mudah yang bisa kita karang : Misalkan sebuah aplikasi perbankan menjanjikan pembayaran bunga pada tanggal 25 setiap bulannya. Tetapi karena kesalahan ketik, user memasukkan tanggal 35. Karena aplikasi tidak mengeluarkan Exception, data tersebut tersimpan dengan mulus di database dan akibatnya pembayaran bunga molor 10 hari dari yang sudah dijanjikan. Satu atau dua nasabah dengan rekening yang kecil mungkin tidak terlalu ambil pusing. Tetapi bagaimana dengan nasabah dengan rekening yang besar yang memang setiap bulannya menanti-nanti tanggal 25??

Untuk mengantisipasi hal ini, kita dapat ‘meminta’ DateFormat untuk menghilangkan rasa toleransinya. Yaitu dengan menambahkan setLenient(false). Dengan tidak adanya toleransi dari DateFormat maka input “20090635″ akan ditolak dan aplikasi akan mengeluarkan Exception dan Business Error pun dapat dihindari. Di bawah ini adalah contoh kode program yang menghilangkan rasa toleransi dari DateFormat :

  public class Main {
    public static void
main(String... args) {
      String pattern = "yyyyMMdd";
      DateFormat dateFormatter = new SimpleDateFormat(pattern);
      dateFormatter.setLenient(
false);
      String _35_Juni_09 = "20090635";

      try {
        System.out.println(dateFormatter.parse(_35_Juni_09));
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
  }

No Comments Yet »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.