
Hai, teman-teman! Pada Artikel kali ini kita akan membahas cara membuat program untuk memprediksi otonan Bali dengan menggunakan bahasa pemerograman C. Mungkin sebagian dari kalian pernah denger istilah “otonan” yang berhubungan sama kalender tradisional Bali. Di artikel ini, kita akan bahas satu per satu kode yang ada, mulai dari pengecekan tahun kabisat, penambahan dan pengurangan hari, sampai simulasi pergerakan hari untuk menemukan pola target.
Pendahuluan
Di dunia pemrograman, kita nggak cuma belajar logika dan algoritma, tapi juga bisa mengintegrasikan elemen budaya ke dalam kode. Nah, kode yang akan kita bahas kali ini merupakan contoh bagaimana cara memprediksi tanggal otonan Bali. Otonan sendiri berkaitan dengan perhitungan tanggal dalam kalender tradisional Bali yang melibatkan tiga pola, yaitu Pancawara, Saptawara, dan Wuku. Dengan menggunakan beberapa fungsi sederhana dalam bahasa C, kode ini akan menghitung tanggal target berdasarkan pergerakan hari dari posisi dasar. Yuk, simak penjelasan berikut!
Mengenal Kode Secara Keseluruhan
Sebelum kita masuk ke detail setiap bagiannya, mari kita lihat dulu keseluruhan kode yang akan kita bahas. Kode berikut menggabungkan beberapa fungsi untuk melakukan perhitungan tanggal, validasi input, dan simulasi pergerakan hari hingga mendapatkan pola target:
#include <stdio.h> #include <string.h> // Fungsi mengecek tahun kabisat int isLeapYear(int year) { if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return 1; return 0; } // Fungsi untuk menambahkan offset hari secara manual void addDays(int *day, int *month, int *year, int offset) { int md[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (int i = 0; i < offset; i++) { (*day)++; // Sesuaikan jumlah hari Februari jika tahun kabisat if (*month == 2 && isLeapYear(*year)) md[2] = 29; else md[2] = 28; if (*day > md[*month]) { *day = 1; (*month)++; if (*month > 12) { *month = 1; (*year)++; } } } } // Fungsi untuk mengurangkan offset hari secara manual void subtractDays(int *day, int *month, int *year, int offset) { int md[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (int i = 0; i < offset; i++) { (*day)--; if (*month == 2 && isLeapYear(*year)) md[2] = 29; else md[2] = 28; if (*day < 1) { (*month)--; if (*month < 1) { *month = 12; (*year)--; } // Set hari ke hari terakhir bulan tersebut if (*month == 2 && isLeapYear(*year)) *day = 29; else *day = md[*month]; } } } // Fungsi untuk mencari indeks dari array string int findIndex(char *array[], int size, char *input) { for (int i = 0; i < size; i++) { if (strcmp(array[i], input) == 0) return i; } return -1; // Jika tidak ditemukan } int main() { // Inisialisasi array pola (dengan input string) char *P[5] = {"Umanis", "Paing", "Pon", "Wage", "Kliwon"}; char *S[7] = {"Redite", "Soma", "Anggara", "Buda", "Wraspati", "Sukra", "Saniscara"}; char *W[30] = {"Sinta", "Landep", "Ukir", "Kulantir", "Tolu", "Gumbreg", "Wariga", "Warigadean", "Julungwangi", "Sungsang", "Dunggulan", "Kuningan", "Langkir", "Medangsia", "Pujut", "Pahang", "Krulut", "Merakih", "Tambir", "Medangkungan", "Matal", "Uye", "Menail", "Prangbakat", "Bala", "Ugu", "Wayang", "Kelawu", "Dukut", "Watugunung"}; // Posisi dasar yang diset: P5, S5, W3 (indeks: P[4], S[4], W[2]) int startP = 4, startS = 4, startW = 2; printf("Posisi dasar di-set ke: %s %s %s\n", P[startP], S[startS], W[startW]); // Input target pola dari user menggunakan string char inputP[20], inputS[20], inputW[20]; printf("Masukkan Saptawara target: "); scanf("%s", inputS); printf("Masukkan Pancawara target: "); scanf("%s", inputP); printf("Masukkan Wuku target: "); scanf("%s", inputW); // Konversi input string ke indeks (pada array P, S, W) int targetP = findIndex(P, 5, inputP); int targetS = findIndex(S, 7, inputS); int targetW = findIndex(W, 30, inputW); // Validasi input if (targetP == -1 || targetS == -1 || targetW == -1) { printf("Input tidak valid. Pastikan ejaan benar!\n"); return 1; } // Simulasi pergerakan hari dari posisi dasar ke posisi target int hariOffset = 0; int nowP = startP, nowS = startS, nowW = startW; while (nowP != targetP || nowS != targetS || nowW != targetW) { hariOffset++; // maju 1 hari // Update pola: setiap hari Pancawara dan Saptawara naik secara siklis nowP = (nowP + 1) % 5; nowS = (nowS + 1) % 7; // Update Wuku: naik 1 jika Saptawara kembali ke awal (setelah increment) if (nowS == 0) { nowW = (nowW + 1) % 30; } } printf("Target ditemukan setelah %d hari dari posisi dasar.\n", hariOffset); // Perhitungan tanggal dasar: // Tanggal dasar (untuk posisi dasar P5 S5 W3) adalah 1 Agustus 2024. int baseDay = 1, baseMonth = 8, baseYear = 2024; // Hitung tanggal baseOccurrence untuk pola target dengan menambahkan hariOffset int tarDay = baseDay, tarMonth = baseMonth, tarYear = baseYear; addDays(&tarDay, &tarMonth, &tarYear, hariOffset); // Tampilkan tanggal base untuk pola target dengan nama bulan printf("Tanggal base untuk pola target: %d ", tarDay); printf((tarMonth == 1) ? "Januari" : (tarMonth == 2) ? "Februari" : (tarMonth == 3) ? "Maret" : (tarMonth == 4) ? "April" : (tarMonth == 5) ? "Mei" : (tarMonth == 6) ? "Juni" : (tarMonth == 7) ? "Juli" : (tarMonth == 8) ? "Agustus" : (tarMonth == 9) ? "September" : (tarMonth == 10) ? "Oktober" : (tarMonth == 11) ? "November" : "Desember"); printf(" %d\n", tarYear); // User memasukkan batas tahun int lowerYear, upperYear; printf("Masukkan batas tahun (misal: 1960 1970): "); scanf("%d %d", &lowerYear, &upperYear); // Karena pola berulang tiap 210 hari, kita akan menghasilkan daftar tanggal // yang sesuai, baik dengan mengurangkan (ke masa lalu) maupun menambahkan (ke masa depan) // sehingga tanggal yang dihasilkan berada dalam rentang [lowerYear, upperYear]. // Cari tanggal terkecil (awal) yang masih >= batas bawah. // Mulai dari baseOccurrence (tarDay, tarMonth, tarYear) int listDay = tarDay, listMonth = tarMonth, listYear = tarYear; // Salin nilai awal ke variabel bantu untuk penurunan int tempDay = listDay, tempMonth = listMonth, tempYear = listYear; // Kurangi 210 hari secara berulang selama tanggal masih >= batas bawah while (tempYear > lowerYear || (tempYear == lowerYear)) { int prevDay = tempDay, prevMonth = tempMonth, prevYear = tempYear; subtractDays(&prevDay, &prevMonth, &prevYear, 210); if (prevYear < lowerYear) break; tempDay = prevDay; tempMonth = prevMonth; tempYear = prevYear; } // Jika hasil pengurangan melewati batas bawah, tambahkan 210 hari sekali if (tempYear < lowerYear) { addDays(&tempDay, &tempMonth, &tempYear, 210); } // Tampilkan daftar tanggal dalam rentang yang diberikan printf("\nDaftar tanggal untuk pola target dalam rentang %d - %d:\n", lowerYear, upperYear); while (tempYear < upperYear || (tempYear == upperYear)) { char *namaBulan[13] = {"", "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"}; printf("%d %s %d\n", tempDay, namaBulan[tempMonth], tempYear); addDays(&tempDay, &tempMonth, &tempYear, 210); } return 0; }
Penjelasan Code
1. Bagian Header dan Library
Pada awal kode, terdapat dua baris penting:
#include <stdio.h> #include <string.h>
Baris ini menyertakan library standar untuk input/output dan fungsi-fungsi pengolahan string. Dengan adanya kedua library ini, kita bisa menggunakan fungsi seperti printf()
, scanf()
, dan strcmp()
yang sangat berguna di seluruh program.
2. Fungsi Utilitas
2.1. Fungsi isLeapYear()
Fungsi ini bertugas mengecek apakah sebuah tahun merupakan tahun kabisat atau tidak. Logika yang digunakan adalah:
-
Jika tahun habis dibagi 4 dan tidak habis dibagi 100, atau habis dibagi 400, maka fungsi mengembalikan nilai 1 (true).
-
Jika tidak, fungsi mengembalikan 0 (false).
Pengecekan tahun kabisat penting karena jumlah hari di bulan Februari berubah (29 hari pada tahun kabisat).
2.2. Fungsi addDays()
Fungsi ini digunakan untuk menambahkan sejumlah hari ke tanggal yang diberikan. Di dalamnya terdapat:
-
Array
md
yang menyimpan jumlah hari tiap bulan. -
Penyesuaian khusus untuk bulan Februari jika tahun tersebut kabisat.
-
Logika perulangan yang menambahkan satu hari per iterasi. Jika hari melebihi batas jumlah hari di bulan tertentu, maka hari di-reset ke 1 dan bulan bertambah, dan jika bulan sudah melewati Desember, tahun juga akan bertambah.
2.3. Fungsi subtractDays()
Kebalikan dari addDays()
, fungsi ini mengurangkan sejumlah hari dari tanggal. Logikanya:
-
Mengurangi hari satu per satu.
-
Jika hasil pengurangan membuat hari kurang dari 1, maka bulan akan dikurangi.
-
Jika bulan kurang dari 1, maka tahun dikurangi dan bulan di-set ke 12.
-
Penyesuaian jumlah hari pada bulan Februari juga dilakukan sesuai dengan apakah tahun tersebut kabisat atau tidak.
2.4. Fungsi findIndex()
Fungsi ini berguna untuk mencari indeks suatu string dalam array. Dalam kode ini, terdapat tiga array untuk:
-
Pancawara (P): Misalnya "Umanis", "Paing", dan seterusnya.
-
Saptawara (S): Misalnya "Redite", "Soma", dll.
-
Wuku (W): Terdiri dari 30 nama wuku khas Bali.
Fungsi findIndex()
membandingkan input dari user dengan tiap elemen array menggunakan strcmp()
. Jika ditemukan kecocokan, maka fungsi mengembalikan indeks dari elemen tersebut. Jika tidak ditemukan, maka mengembalikan -1 sebagai indikator input tidak valid.
3. Alur Program di Fungsi main()
3.1. Inisialisasi dan Penetapan Posisi Dasar
Di awal fungsi main()
, program mendeklarasikan tiga array yang berisi pola-pola kalender Bali. Posisi dasar yang ditetapkan adalah:
-
Pancawara ke-5 (indeks 4)
-
Saptawara ke-5 (indeks 4)
-
Wuku ke-3 (indeks 2)
Posisi dasar ini menjadi acuan awal untuk perhitungan tanggal selanjutnya.
3.2. Input Target Pola dan Validasi
Program kemudian meminta input dari user berupa:
-
Saptawara target
-
Pancawara target
-
Wuku target
Input ini diubah menjadi indeks melalui fungsi findIndex()
. Jika ada input yang tidak valid (misalnya ejaan salah), program akan menampilkan pesan error dan menghentikan eksekusi.
3.3. Simulasi Pergerakan Hari
Setelah validasi, program menghitung berapa hari yang diperlukan untuk mencapai kombinasi pola target dari posisi dasar. Prosesnya:
-
Setiap iterasi, variabel
hariOffset
bertambah satu. -
Indeks Pancawara dan Saptawara diperbarui secara siklis menggunakan operasi modulo.
-
Indeks Wuku hanya akan naik ketika Saptawara kembali ke awal (indeks 0).
Proses ini terus berlangsung hingga kombinasi pola yang diinginkan tercapai, sehingga hariOffset
menyimpan jumlah hari yang dibutuhkan.
3.4. Perhitungan Tanggal Target
Tanggal dasar yang digunakan adalah 1 Agustus 2024. Dengan bantuan fungsi addDays()
, tanggal dasar ini ditambahkan dengan nilai hariOffset
sehingga menghasilkan tanggal target yang sesuai dengan pola yang dicari. Tanggal ini kemudian ditampilkan dengan format yang melibatkan nama bulan menggunakan operator ternary.
3.5. Menampilkan Daftar Tanggal dalam Rentang Tahun
Selain menghitung tanggal target, program juga menyediakan fitur untuk menampilkan daftar tanggal yang sesuai dengan pola target dalam rentang tahun tertentu. User akan diminta memasukkan batas bawah dan batas atas tahun, misalnya 1960 hingga 1970. Karena pola kalender Bali berulang setiap 210 hari, program:
-
Mengurangi tanggal (menggunakan
subtractDays()
) untuk menemukan tanggal terkecil yang masih berada di atas batas bawah. -
Menambahkan 210 hari secara berulang hingga tanggal yang dihasilkan mencapai atau melewati batas atas. Setiap tanggal yang dihasilkan kemudian dicetak dengan format hari, nama bulan, dan tahun.
Kesimpulan
Kode ini merupakan contoh menarik bagaimana kita bisa menggabungkan perhitungan tanggal dalam bahasa C dengan data tradisional Bali. Dari pengecekan tahun kabisat hingga penambahan dan pengurangan hari, setiap fungsi memiliki peran penting untuk memastikan hasil perhitungan tanggal tepat dan akurat. Melalui simulasi pergerakan hari, kita bisa menemukan kombinasi pola target yang diinginkan, kemudian menghitung tanggal target tersebut berdasarkan tanggal dasar. Selain itu, fitur untuk menampilkan daftar tanggal dalam rentang tahun tertentu menambah nilai praktis dari kode ini.
Dengan mempelajari kode ini, kamu nggak cuma belajar bagaimana cara mengelola tanggal dalam pemrograman, tapi juga bisa melihat bagaimana tradisi dan budaya dapat diintegrasikan ke dalam aplikasi digital. Semakin sering kamu berlatih dan bereksperimen, semakin paham juga logika di balik perhitungan dan penggunaan array untuk menyimpan data tradisional.
Semoga penjelasan terstruktur ini membantu kamu memahami alur kerja kode prediksi tanggal otonan Bali dengan lebih mudah. Jangan ragu untuk mencoba memodifikasi kode ini—misalnya dengan mengganti tanggal dasar, menambah fitur validasi, atau bahkan mengembangkan antarmuka sederhana agar program lebih interaktif. Kalau ada pertanyaan atau ide pengembangan lebih lanjut, silakan tinggalkan komentar di bawah. Yuk, terus eksplorasi dunia ngoding dengan kreativitas dan semangat!
Selamat mencoba dan semangat terus dalam belajar pemrograman!