Minggu, 27 September 2026

Presenting Relative Time

Untuk versi bahasa Indonesia dari entri ini, klik di sini.

Hello! This time, I want to discuss about ways to present relative time.

To present time data, e.g. time of delivery and last modified time, usually we use relative time alongside absolute time. What are the differences?

Absolute time is a time which is based on a specific fixed event (epoch). For example, the 1 CE is based on Isa's/Jesus' birth PBUH. The 1 Hijri is based on the migration of Muhammad PBUH from Mecca to Medina.

Relative time is a time distance or time difference between two events, usually from an event to current time. For example, this post was published a few minutes ago. The October month is coming in 4 days.

One of the advantages of relative time is that there is no need to take time zone into account when understanding the meaning of the displayed date/time. For example, in contents targeting international readers, sometimes on different time zones are displayed to make it easier for readers. If there are supports for updating content dynamically, many will choose to show countdowns alongside its absolute time, one of the ways to present relative time.

Ways to Present Relative Time

There are many ways to present relative times. For example, the ones on websites or applications usually use minute unit as their smallest unit. The next ones are hours, days, weeks or months, and so on. The next unit is used after it reaches 1 unit, i.e. the hour unit after 60 minutes, the day unit after 24 hours, and so on.

It does not have to be that way. For relative time, I prefer if the next unit is used after it reaches 1.5 or 2 of the unit. For example, the hour unit after 90 or 120 minutes, the day unit after 36 or 48 hours, and so on.

Another thing is that there are those who round downward (floor), round upward (ceil), or round to the nearest (round). I choose to round downward.

The problem is that most libraries (1) use one unit as the limit for the next unit, (2) use weird limits in my opinion, or (3) round upward.

Because of that, this time, I want to make my own version as I want. What I want is a version which uses second as its smallest unit, uses the next unit after reaching 2 of the unit, and rounds downward.

Relative Time Conversion Function

I am going to use JavaScript language. One of the reasons is that this code can be tested in this very page.

Below is a basic definition of relativeTime function which accepts two parameters which are time of the event and epoch for calculating the relative time. The epoch parameter is optional and it defaults to current time at call.

function relativeTime(time, epoch) {
    if (epoch == undefined) {
        epoch = new Date();
    }
    // The diff value is in milliseconds.
    let diff = time.getTime() - epoch.getTime();
    // ...
}

The diff variable is for determining which text to be shown.

The first case is when the absolute value of diff is smaller than 1 the smallest unit being used.

// If diff is below 1 second,
if (Math.abs(diff) < 1000) {
    return "now";
}

For the next step, we get the sign of diff. After that, we make diff be always positive by using absolute function to make determining which unit to be used easier.

// A negative diff value means that the event is in the past.
const past = diff < 0;
diff = Math.abs(diff); // Absolute value

The next parts are repeated based on units used. There are three main steps: (1) converting diff to the next unit, (2) checking whether is below or equal to 2 of the unit, and (3) presenting based on past vs. non-past.

diff /= 1000; // Milliseconds to seconds
if (diff <= 2 * 60) {
    return past ? // "ago" vs. "in"
        Math.floor(diff) + " seconds ago" :
        "in " + Math.floor(diff) + " seconds";
}
// The above code is repeated for minutes, hours, and days.

Below is the complete code.

// Relative time in English
function relativeTime(time, epoch) {
    if (epoch == undefined) {
        epoch = new Date();
    }
    // The diff value is in milliseconds.
    let diff = time.getTime() - epoch.getTime();
    // If diff is below 1 second,
    if (Math.abs(diff) < 1000) {
        return "now";
    }
    // A negative diff value means that the event is in the past.
    const past = diff < 0;
    diff = Math.abs(diff); // Absolute value
    // Seconds //
    diff /= 1000; // Milliseconds to seconds
    if (diff <= 2 * 60) {
        return past ?
            Math.floor(diff) + " seconds ago" :
            "in " + Math.floor(diff) + " seconds";
    }
    // Minutes //
    diff /= 60; // Seconds to minutes
    if (diff <= 2 * 60) {
        return past ?
            Math.floor(diff) + " minutes ago" :
            "in " + Math.floor(diff) + " minutes";
    }
    // Hours //
    diff /= 60; // Minutes to hours
    if (diff <= 2 * 24) {
        return past ?
            Math.floor(diff) + " hours ago" :
            "in " + Math.floor(diff) + " hours";
    }
    // Days //
    diff /= 24; // Hours to days
    return past ?
        Math.floor(diff) + " days ago" :
        "in " + Math.floor(diff) + " days";
}

Example result: The publication of this post is when?

Final Words

Even though we can create our own relative function ourselves, we may not be able to apply it for applications created by other parties. Because of that, I hope that every application has a way to see absolute time alongside relative time.

Basically, I prefer to be able to see exact values instead of approximation if possible. Even this blog also chooses to show publication time using absolute time. Relative times usually shown usually lose their precisions. For example, absolute time is usually precise until seconds, meanwhile relative time usually loses its precision over time (minutes ago, hours ago, and so on).

That's all I write this time. Hope this helps!

Menyajikan Waktu Relatif

For English version from this entry, click here.

Halo! Kali ini, aku mau membahas tentang cara menyajikan waktu relatif.

Ketika ingin menyajikan data waktu, misal waktu pengiriman dan waktu terakhir diubah, biasanya kita menggunakan waktu relatif bersamaan dengan waktu absolut/mutlak. Apa bedanya?

Waktu absolut/mutlak adalah waktu yang didasarkan pada kejadian tertentu yang bersifat tetap (epoch). Misalnya, tahun 1 Masehi didasarkan pada kejadian kelahiran Nabi Isa a.s. Tahun 1 Hijriah didasarkan pada kejadian hijrah Nabi Muhammad saw. dari Makkah ke Madinah.

Waktu relatif adalah jarak waktu dari dua kejadian, biasanya dari suatu kejadian ke waktu saat ini. Misalnya, tulisan ini diterbitkan sekian menit yang lalu. Bulan Oktober akan tiba dalam 4 hari.

Salah satu keunggulan waktu relatif adalah tidak perlu memperhitungkan zona waktu saat memahami maksud dari tanggal/waktu yang ditampilkan. Misalnya, dalam konten-konten dengan target internasional, ditampilkan beberapa waktu dalam beberapa zona waktu untuk memudahkan para pembaca. Bila ada dukungan untuk pembaruan konten secara dinamis, banyak yang memilih untuk menampilkan hitung mundur juga selain waktu absolut/mutlak, salah satu cara menyajikan waktu relatif.

Cara Menyajikan Waktu Relatif

Ada banyak cara menyajikan waktu relatif. Sebagai contoh, yang ada di situs web atau aplikasi itu biasanya pakai satuan menit sebagai satuan terkecilnya. Selanjutnya adalah satuan jam, hari, pekan atau bulan, dan seterusnya. Satuan berikutnya dipakai setelah mencapai sebanyak satu satuannya, yaitu satuan jam setelah 60 menit, satuan hari setelah 24 jam, dan seterusnya.

Namun, ada juga cara lainnya. Untuk waktu relatif, aku lebih suka bila satuan berikutnya baru dipakai setelah mencapai sebanyak 1,5 atau 2 satuannya. Misalnya, satuan jam setelah 90 atau 120 menit, satuan hari setelah 36 atau 48 jam, dan seterusnya.

Selain itu, ada juga yang membulatkan ke bawah (floor), membulatkan ke atas (ceil), atau membulatkan ke terdekat (round). Aku memilih untuk membulatkan ke bawah.

Hanya saja, kebanyakan pustaka (library) yang ada itu (1) menggunakan batas satu satuan untuk berikutnya, (2) menggunakan batas-batas yang aneh menurutku, atau (3) membulatkan ke atas.

Oleh karena itu, kali ini, aku ingin membuat versiku sesuai keinginanku. Yang kuinginkan adalah versi yang menggunakan detik sebagai satuan terkecil, menggunakan satuan berikutnya setelah mencapai 2 satuannya, dan membulatkan ke bawah.

Fungsi Konversi Waktu Relatif

Aku akan menggunakan bahasa JavaScript. Salah satu alasannya adalah agar ini bisa dicoba langsung di halaman ini juga.

Berikut adalah definisi awal fungsi waktuRelatifID yang menerima dua parameter, yaitu waktu yang dimaksud dan acuan dalam menyajikan waktu relatif. Nilai acuan bersifat opsional dan bernilai bawaan waktu saat dipanggil.

function waktuRelatifID(waktu, acuan) {
    if (acuan == undefined) {
        acuan = new Date();
    }
    // Nilai beda dalam milidetik.
    let beda = waktu.getTime() - acuan.getTime();
    // ...
}

Nilai beda itu yang akan digunakan dalam menentukan yang akan ditampilkan.

Kasus pertama adalah bila nilai mutlak beda lebih kecil daripada satu satuan terkecil yang akan digunakan.

// Jika beda di bawah 1 detik,
if (Math.abs(beda) < 1000) {
    return "sekarang";
}

Untuk selanjutnya, kita akan mengambil tanda dari beda. Setelah itu, kita buat beda menjadi selalu positif dengan fungsi nilai mutlak untuk memudahkan dalam menentukan satuan yang akan digunakan.

// Nilai beda negatif berarti kejadiannya lampau.
const lampau = beda < 0;
beda = Math.abs(beda); // Nilai mutlak

Bagian-bagian berikutnya berulang mengikuti satuan-satuan yang digunakan. Ada tiga bagian utama: (1) konversi beda ke satuan berikutnya, (2) pemeriksaan nilai 2 satuannya, dan (3) menyajikan berdasarkan lampau vs. tidak lampau.

beda /= 1000; // Milidetik ke detik
if (beda <= 2 * 60) {
    return lampau ? // "yang lalu" vs. "dalam"
        Math.floor(beda) + " detik yang lalu" :
        "dalam " + Math.floor(beda) + " detik";
}
// Kode di atas diulangi untuk menit, jam, dan hari.

Berikut adalah kode lengkapnya.

// Waktu relatif dalam bahasa Indonesia
function waktuRelatifID(waktu, acuan) {
    if (acuan == undefined) {
        acuan = new Date();
    }
    // Nilai beda dalam milidetik.
    let beda = waktu.getTime() - acuan.getTime();
    // Jika beda di bawah 1 detik,
    if (Math.abs(beda) < 1000) {
        return "sekarang";
    }
    // Nilai beda negatif berarti kejadiannya lampau.
    const lampau = beda < 0;
    beda = Math.abs(beda); // Nilai mutlak
    // Detik //
    beda /= 1000; // Milidetik ke detik
    if (beda <= 2 * 60) {
        return lampau ?
            Math.floor(beda) + " detik yang lalu" :
            "dalam " + Math.floor(beda) + " detik";
    }
    // Menit //
    beda /= 60; // Detik ke menit
    if (beda <= 2 * 60) {
        return lampau ?
            Math.floor(beda) + " menit yang lalu" :
            "dalam " + Math.floor(beda) + " menit";
    }
    // Jam //
    beda /= 60; // Menit ke jam
    if (beda <= 2 * 24) {
        return lampau ?
            Math.floor(beda) + " jam yang lalu" :
            "dalam " + Math.floor(beda) + " jam";
    }
    // Hari //
    beda /= 24; // Jam ke hari
    return lampau ?
        Math.floor(beda) + " hari yang lalu" :
        "dalam " + Math.floor(beda) + " hari";
}

Contoh hasilnya: Tulisan ini diterbitkan kapan?

Penutup

Meskipun bisa membuat fungsi relatif sendiri, kita belum tentu bisa menerapkannya untuk aplikasi yang dibuat oleh pihak lain. Oleh karena itu, aku berharap bahwa tiap aplikasi memiliki cara tertentu untuk bisa melihat waktu absolut/mutlak selain melihat waktu relatif.

Pada dasarnya, aku lebih memilih bisa melihat nilai pasti daripada perkiraan jika memungkinkan. Blog ini pun juga memilih untuk menyajikan waktu penerbitan dengan waktu absolut/mutlak. Waktu relatif yang banyak disajikan itu biasanya kehilangan presisinya. Misalnya, waktu absolut/mutlak biasanya memiliki presisi hingga detik, sedangkan waktu relatif pada umumnya makin kurang presisi seiring waktu (menit yang lalu, jam yang lalu, dst.).

Cukup sekian tulisanku kali ini. Semoga bermanfaat!

Senin, 31 Agustus 2026

Gini dan Desil

Halo! Kali ini, kita bahas tentang ilmu statistika.

Beberapa waktu lalu, sempat ramai mengenai desil dan keanehan-keanehan yang ada pada saat ini. Namun, aku ingin membahas lebih banyak dari sisi statistika, dimulai dari kuantil.

Kuantil (Desil dan Sebagainya)

Kuantil adalah cara untuk menentukan letak suatu data tunggal dalam sampel/populasi. Kuartil adalah cara untuk mengelompokkan sampel/populasi menjadi 4 tingkat/kelompok. Desil mengelompokkan menjadi 10 kelompok. Persentil mengelompokkan menjadi 100 kelompok.

Ilustrasi tiga baris yang menunjukkan pembagian sebanyak 4 kelompok yang disebut kuartil, 10 kelompok yang disebut desil, dan 100 kelompok yang disebut persentil.
Ilustrasi kuartil (4), desil (10), dan persentil (100)

Sebagai contoh, ada contoh data berikut yang akan dihitung kuartilnya. Cara membaginya adalah dengan mengurutkan dan kemudian membaginya menjadi empat.

7633569823812451
↓↓↓   Urutkan   ↓↓↓
1122333455667889
↓↓↓   Partisi   ↓↓↓
1122333455667889
Kuartil 1Kuartil 2Kuartil 3Kuartil 4

Setelah data dibagi menjadi empat kelompok itu, tiap kelompok bisa diukur ciri-cirinya, seperti jumlah dan rata-rata.

KuartilJumlahRata-Rata
Q16 (8,2%)1,50
Q213 (17,8%)3,25
Q322 (30,1%)5,50
Q432 (43,8%)8,00
Total73 (100%)

Selain melihat ukuran-ukuran tiap kelompok, kita juga bisa melihat ukuran kumulatif tiap kelompok. Kumulatif yang dimaksud adalah mengelompokkan suatu kelompok dengan kelompok-kelompok sebelumnya (atau setelahnya, tergantung urutan yang dimaksud). Misalnya, kumulatif sampai kuartil ketiga dari bawah adalah gabungan dari kuartil pertama, kuartil kedua, dan kuartil ketiga.

KuartilJumlah Kumulatif
Q16 (8,2%)
Q219 (26,0%)
Q341 (56,2%)
Q473 (100,0%)

Ukuran kumulatif seperti di atas digunakan dalam banyak hal. Di bidang pengolahan citra misalnya, ukuran kumulatif digunakan untuk meningkatkan kualitas kontras citra dengan metode histogram equalization. Kali ini, yang akan kita bahas adalah contoh di bidang ekonomi.

Koefisien Gini

Koefisien Gini adalah ukuran penyebaran data yang dimaksudkan untuk mewakili ketimpangan pendapatan, ketimpangan pemasukan, atau ketimpangan konsumsi dalam sebuah bangsa atau sebuah kelompok sosial. Koefisien ini memiliki rentang nilai dari 0 (tidak ada ketimpangan) hingga 1 atau 100% (ketimpangan maksimum). Nama koefisien ini diambil dari nama ahli sosiologi Corrado Gini.

Sebagai contoh, koefisien Gini pendapatan masyarakat di keseluruhan Uni Eropa pada tahun 2025 sebesar 29,2% (Eurostat, 2026). Koefisiennya di Amerika Serikat pada tahun 2024 sebesar 41,8% (World Bank, 2024) dan di Indonesia pada tahun 2025 sebesar 34,4% (World Bank, 2025).

Secara matematis, koefisien Gini dihitung menggunakan kurva Lorenz. Kurva Lorenz adalah gambaran persebaran pendapatan atau kekayaan. Kurva ini adalah grafik kumulatif yang menyatakan sekian persen sampel/populasi terbawah memiliki sekian persen total pendapatan atau kekayaan. Selain kurva Lorenz, ada juga garis kesetaraan yang dimulai dari kiri-bawah (0, 0) ke kanan-atas (1, 1). Koefisien Gini adalah perbandingan luas di bawah garis kesetaraan (X) dan di atas kurva Lorenz dibagi dengan luas bawah kurva Lorenz (Y). Gambar berikut menggambarkan luasan yang dimaksud.

Garis kesetaraan, kurva Lorenz, daerah X, dan daerah Y

Pada praktiknya, kurva Lorenz tidak bisa bersifat kontinu dan hanya bisa didekati secara diskret. Salah satu cara yang bisa digunakan adalah dengan menggunakan kuantil yang tersedia karena menghitung jutaan (bahkan ratusan juta) data sekaligus untuk menghitung kurva Lorenz terlalu berat dan rawan terkena derau dalam data (overfitting).

Sebagai contoh, misalkan 50% populasi terbawah hanya memiliki 20% kekayaan. Kurva Lorenz bisa didekati dengan bentuk trapesium. Berikut ilustrasinya.

Contoh kasus dua kelompok

Koefisien Gini adalah luas X dibagi luas X + Y. Untuk kasus ini, misalkan tidak ada yang memiliki kekayaan minus, maka luas X + Y adalah 0,5. Kita bisa menggunakan rumus luas trapesium untuk menghitung luas Y.

Y = (1/2) × (0% + 20%) × 50% + (1/2) × (20% + 100%) × 50%

Y = 0,5 × 0,2 × 0,5 + 0,5 × 1,2 × 0,5

Y = 0,05 + 0,3

Y = 0,35

Kemudian, kita hitung koefisien Gini darinya.

Gini = X / (X + Y)

Gini = (0,5 - Y) / (0,5)

Gini = (0,5 - 0,35) / (0,5)

Gini = (0,15) / (0,5)

Gini = 0,3 = 30%

Hasilnya ditunjukkan di ilustrasi di atas.

Gini ke Desil

Kita juga bisa memperkirakan nilai tiap desil berdasarkan koefisien Gini yang diketahui. Meski bentuk kurva Lorenz yang berbeda bisa memiliki koefisien Gini yang sama, setidaknya kita jadi mendapat gambaran secara kasar dengan asumsi-asumsi tertentu yang kita tentukan sebelumnya.

Kekayaan masyarakat di Indonesia

Sebagai contoh, koefisien Gini kekayaan masyarakat di Indonesia pada tahun 2021 sebesar 78,2% (Credit Suisse, 2022), di atas Kamboja (78,3%) dan di bawah Ginea-Bisau dan Tunisia (78,0%).

Dengan asumsi kekayaan masyarakat tiap desil mengikuti pola cxk + 10-4 dengan x adalah nilai desil dibagi 10 lalu ditambah 0,05. Dengan metode bisection, kita bisa mendekati nilai k dan c, yaitu k ≈ 7,80014 dan c ≈ 9,04713.

Perkiraan persebaran kekayaan untuk koefisien Gini sebesar 78,2%.

Dari grafik di atas, sangat terlihat perbedaan persentase kekayaan tiap desil, terutama desil-desil atas. Desil 10 bahkan menguasai sekitar 60% kekayaan masyarakat jika menggunakan asumsi di atas.

Pendapatan masyarakat di Indonesia

Kita ambil contoh lain. Koefisien Gini pendapatan masyarakat di Indonesia pada tahun 2025 sebesar 34,4% (World Bank, 2025). Selain itu, desil ke-10 pendapatan masyarakat menguasai 41,24% total pendapatan nasional (World Inequality Database, 2024). Dengan asumsi pola desil yang sama, kecuali desil 10 yang sudah diketahui, kita bisa mendekati nilai k dan c, yaitu k ≈ 0,13625 dan c ≈ 1,14898.

Perkiraan persebaran pendapatan untuk koefisien Gini sebesar 34,4% dengan desil ke-10 pendapatan masyarakat menguasai 41,24% total pendapatan nasional

Dari grafik di atas, sangat timpang persentase pendapatan desil ke-10 bila dibandingkan dengan desil-desil lainnya.

Desil vs. Persentil

Dari kedua contoh pemodelan di atas, desil ke-10 sangat timpang bila dibandingkan dengan desil-desil lain. Hal ini membuat sebagian bertanya, "Apakah desil sudah cukup detail?" Hal ini diperkuat oleh data dari World Inequality Database (2024) yang menunjukkan persebaran pendapatan dan kekayaan masyarakat yang sangat timpang. Berikut data untuk Indonesia pada tahun 2024.

KuantilPendapatanKekayaan
1% teratas17,85%21,32%
10% teratas46,86%60,38%
50% terbawah12,45%2,44%

Persentil ke-100 menguasai 38,09% pendapatan dan 35,31% kekayaan desil ke-10. Hal ini menunjukkan bahwa data tiap desil perlu dilengkapi dengan data tiap persentil, terutama untuk desil ke-10. Ini adalah kritik kepada lembaga-lembaga yang mengurusi statistik penduduk.

Dalam operasional sistem, biasa dikenal ukuran statistik P90, P95, dan P99 (90% terbawah, 95% terbawah, dan 99% terbawah) untuk mengetahui kasus-kasus yang jarang terjadi (anomali) dalam rentang waktu tertentu. Kalau semisal lembaga-lembaga tersebut belum bisa (atau belum berani) memublikasikan keseluruhan persentil, setidaknya publikasikan juga ketiga bagian/kuantil itu di samping data tiap desil yang sudah ada.

Penutup

Kalau kita melihat ketimpangan yang ada di sekitar, rasanya memang menyedihkan, terlebih lagi banyak yang seharusnya berwenang itu justru skill issue dalam menanganinya (bahkan justru mengisi kantung pribadi). Yang bisa kita lakukan, ya, ikut membantu sesama: rakyat bantu rakyat.

Cukup sekian tulisanku. Semoga kita bisa sukses bersama. Sampai jumpa!