{"id":97,"date":"2010-02-16T13:36:42","date_gmt":"2010-02-16T06:36:42","guid":{"rendered":"http:\/\/sybond.web.id\/2010\/02\/16\/delphi-secondsbetween-bugs\/"},"modified":"2014-05-20T14:20:29","modified_gmt":"2014-05-20T07:20:29","slug":"delphi-secondsbetween-bugs","status":"publish","type":"post","link":"https:\/\/sybond.web.id\/blog\/2010\/02\/16\/delphi-secondsbetween-bugs\/","title":{"rendered":"Delphi SecondsBetween Bugs?"},"content":{"rendered":"<p align=\"justify\">Ada sebuah kasus teknis (<em>programming<\/em>) dalam hal ini adalah Delphi (versi 7, ntahlah di versi-versi yang lain). Tujuannya adalah menghitung selisih waktu detik antara dua buah satuan waktu.<\/p>\n<p align=\"justify\">Waktu awal: <strong>2010\/02\/15 13:51:34<\/strong>, waktu akhir:<strong> 2010\/02\/15 13:51:21<\/strong>.<\/p>\n<p align=\"justify\">Secara kasat mata atau perhitungan manual kita tahu bahwa selisih waktu awal dan waktu akhir adalah 13 detik. Tapi coba hitunglah selisih waktu di atas dengan menggunakan sebuah fungsi di Delphi yang dikhususkan untuk menghitung selisih waktu dalam satuan detik. <em><strong>SecondsBetween<\/strong><\/em>.<\/p>\n<p align=\"justify\">Hasilnya adalah sebuah angka yang tidak sesuai dengan harapan, yaitu 12 detik.<\/p>\n<p align=\"justify\">Namun untuk beberapa kasus, fungsi SecondsBetween memberikan nilai perhitungan yang benar seperti untuk data input:<\/p>\n<p align=\"justify\">Waktu awal: <strong>2010\/02\/15 16:50:13<\/strong>, waktu akhir:<strong> 2010\/02\/15 16:50:14<\/strong>. Hasilnya adalah 1 detik.<\/p>\n<p align=\"justify\">Dan pada akhirnya sampai pada pertanyaan mendasar: <strong>kenapa begitu?<\/strong><\/p>\n<p align=\"justify\">Adakah <em>bugs<\/em> dalam fungsi <strong>SecondsBetween<\/strong>?<\/p>\n<p><!--more--><\/p>\n<p align=\"justify\">Saya sendiri masih belum menemukan rujukan online terkait temuan ini di internet atau forum Delphi (yang saya tau \ud83d\ude00 ) tapi yang jelas hal ini adalah sebuah kesalahan mendasar yang seharusnya tidak terjadi.<\/p>\n<p align=\"justify\"><strong>Lalu solusinya?<\/strong><\/p>\n<p align=\"justify\">Oke, pertama-tama ada beberapa opsi yang saya yakin, jika anda menjadi saya anda pasti akan memilih opsi yang sama. Yaitu:<\/p>\n<ol>\n<li>Membuat fungsi baru dengan tujuan yang sama<\/li>\n<li>Menelusuri penyebab error tersebut, dan melakukan patch<\/li>\n<\/ol>\n<p align=\"justify\">Saya memilih opsi kedua, menelusuri penyebab error tersebut. Dan syukurlah jawabannya dapat segera ditemukan dengan melihat isi dari fungsi tersebut.<\/p>\n<pre class=\"lang:delphi decode:true \">function SecondsBetween(const ANow, AThen: TDateTime):Int64;\r\nbegin\r\n   Result := Trunc(SecondSpan(ANow, AThen));\r\nend;<\/pre>\n<p>Ada yang salah? ya.. ternyata si Borland menggunakan fungsi <em><strong>Trunc<\/strong><\/em> untuk melakukan konversi dari <em>Double<\/em> menjadi <em>Int64<\/em>. Sehingga menyebabkan untuk beberapa nilai selisih tanggal yang dalam delphi merupakan bentukan dari <em>Double<\/em> akan dibulatkan mendekati nol.<\/p>\n<p align=\"justify\">Sebagai solusinya adalah rubah fungsi <em>SecondsBetween<\/em> yang terdapat dalam unit <em>DateUtils<\/em> menjadi:<\/p>\n<pre class=\"lang:delphi decode:true \">function SecondsBetween(const ANow, AThen: TDateTime):Int64;\r\nbegin\r\n   Result := Round(SecondSpan(ANow, AThen));\r\nend;<\/pre>\n<p>Dan masalah terselesaikan.<\/p>\n<p align=\"justify\">Mudah-mudahan kasus yang saya jumpai ini dapat menjadi bahan pembelajaran bagi semuanya. Btw, untuk detil mengenai kegunakan fungsi <em>Round<\/em> silakan baca sendiri saja di dokumentasi help Delphi \ud83d\ude00<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ada sebuah kasus teknis (programming) dalam hal ini adalah Delphi (versi 7, ntahlah di versi-versi yang lain). Tujuannya adalah menghitung selisih waktu detik antara dua buah satuan waktu. Waktu awal: 2010\/02\/15 13:51:34, waktu akhir: 2010\/02\/15 13:51:21. Secara kasat mata atau perhitungan manual kita tahu bahwa selisih waktu awal dan waktu akhir adalah 13 detik. Tapi [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10,11],"tags":[],"_links":{"self":[{"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/posts\/97"}],"collection":[{"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/comments?post=97"}],"version-history":[{"count":2,"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/posts\/97\/revisions"}],"predecessor-version":[{"id":211,"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/posts\/97\/revisions\/211"}],"wp:attachment":[{"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/media?parent=97"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/categories?post=97"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sybond.web.id\/blog\/wp-json\/wp\/v2\/tags?post=97"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}