LOADING
#!/usr/bin/env node
/**
* Wrapper / Age Calculator
* Usage:
* node umurku.js 2000-05-15
* node umurku.js 15/05/2000
* node umurku.js 2000-05-15 --json
*/
import { parseArgs } from 'node:util';
// ====================== HELPER ======================
function parseDate(input) {
if (!input) throw new Error('Tanggal lahir wajib diisi');
// Support: YYYY-MM-DD | DD/MM/YYYY | DD-MM-YYYY
let year, month, day;
if (input.includes('-') && input.split('-')[0].length === 4) {
// YYYY-MM-DD
[year, month, day] = input.split('-').map(Number);
} else if (input.includes('/') || input.includes('-')) {
// DD/MM/YYYY atau DD-MM-YYYY
const parts = input.replace(/-/g, '/').split('/');
[day, month, year] = parts.map(Number);
} else {
throw new Error('Format tanggal tidak dikenali. Gunakan YYYY-MM-DD atau DD/MM/YYYY');
}
const d = new Date(year, month - 1, day);
if (isNaN(d.getTime()) || d.getDate() !== day) {
throw new Error('Tanggal tidak valid');
}
return d;
}
function getMonthDiff(d1, d2) {
let months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth();
months += d2.getMonth();
return months <= 0 ? 0 : months % 12;
}
function getDayName(date) {
return date.toLocaleDateString('id-ID', { weekday: 'long' });
}
function getZodiac(month, day) {
const zodiacs = [
{ name: 'Capricorn', start: [12, 22], end: [1, 19] },
{ name: 'Aquarius', start: [1, 20], end: [2, 18] },
{ name: 'Pisces', start: [2, 19], end: [3, 20] },
{ name: 'Aries', start: [3, 21], end: [4, 19] },
{ name: 'Taurus', start: [4, 20], end: [5, 20] },
{ name: 'Gemini', start: [5, 21], end: [6, 20] },
{ name: 'Cancer', start: [6, 21], end: [7, 22] },
{ name: 'Leo', start: [7, 23], end: [8, 22] },
{ name: 'Virgo', start: [8, 23], end: [9, 22] },
{ name: 'Libra', start: [9, 23], end: [10, 22] },
{ name: 'Scorpio', start: [10, 23], end: [11, 21] },
{ name: 'Sagittarius', start: [11, 22], end: [12, 21] },
];
for (const z of zodiacs) {
const [sm, sd] = z.start;
const [em, ed] = z.end;
if ((month === sm && day >= sd) || (month === em && day <= ed)) {
return z.name;
}
}
return 'Capricorn';
}
function nextBirthday(birth, now) {
let next = new Date(now.getFullYear(), birth.getMonth(), birth.getDate());
if (next < now) {
next = new Date(now.getFullYear() + 1, birth.getMonth(), birth.getDate());
}
const diffMs = next - now;
const daysLeft = Math.ceil(diffMs / (1000 * 60 * 60 * 24));
return {
tanggal: next.toLocaleDateString('id-ID', { day: 'numeric', month: 'long', year: 'numeric' }),
sisa_hari: daysLeft,
};
}
// ====================== CORE CALCULATOR ======================
export function hitungUmur(tanggalLahirInput, tanggalAcuan = new Date()) {
const tglLahir = parseDate(tanggalLahirInput);
const sekarang = new Date(tanggalAcuan);
if (sekarang - tglLahir < 0) {
throw new Error('Tanggal lahir tidak boleh melebihi tanggal acuan!');
}
// --- Logika sama persis dengan umurku.com ---
let tahun = sekarang.getFullYear() - tglLahir.getFullYear();
let bulan = getMonthDiff(tglLahir, sekarang);
let hari = sekarang.getDate() - tglLahir.getDate();
if (hari < 0) {
bulan--;
const bulanLalu = new Date(sekarang.getFullYear(), sekarang.getMonth(), 0).getDate();
hari += bulanLalu;
}
if (bulan < 0) {
tahun--;
bulan += 12;
}
const selisihMs = sekarang - tglLahir;
const totalDetik = Math.floor(selisihMs / 1000);
const totalMenit = Math.floor(totalDetik / 60);
const totalJam = Math.floor(totalMenit / 60);
const totalHari = Math.floor(totalJam / 24);
const next = nextBirthday(tglLahir, sekarang);
return {
tanggal_lahir: tglLahir.toLocaleDateString('id-ID', {
day: 'numeric',
month: 'long',
year: 'numeric',
}),
hari_lahir: getDayName(tglLahir),
zodiak: getZodiac(tglLahir.getMonth() + 1, tglLahir.getDate()),
tanggal_acuan: sekarang.toLocaleDateString('id-ID', {
day: 'numeric',
month: 'long',
year: 'numeric',
}),
umur: {
tahun,
bulan,
hari,
},
total: {
hari: totalHari,
jam: totalJam,
menit: totalMenit,
detik: totalDetik,
},
ulang_tahun_berikutnya: next,
teks: `Pada hari ini, tanggal ${sekarang.toLocaleDateString('id-ID', {
day: 'numeric',
month: 'long',
year: 'numeric',
})}, umur kita adalah: ${tahun} Tahun, ${bulan} Bulan, ${hari} Hari`,
};
}
// ====================== CLI ======================
if (import.meta.url === `file://${process.argv[1]}`) {
try {
const { values, positionals } = parseArgs({
allowPositionals: true,
options: {
json: { type: 'boolean', short: 'j', default: true },
help: { type: 'boolean', short: 'h' },
},
});
if (values.help || positionals.length === 0) {
console.log(`
Penggunaan:
node umurku.js <tanggal-lahir> [--json]
Contoh:
node umurku.js 2000-05-15
node umurku.js 15/05/2000
node umurku.js 2000-05-15 --json
`);
process.exit(0);
}
const hasil = hitungUmur(positionals[0]);
console.log(JSON.stringify(hasil, null, 2));
} catch (err) {
console.error(JSON.stringify({ error: err.message }, null, 2));
process.exit(1);
}
}