Lompat ke isi

Modul:Pendirian: Perbedaan antara revisi

Dari Mippedia bahasa Indonesia, ensiklopedia umum
Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
 
Baris 1: Baris 1:
local p = {}
local p = {}


-- Nama-nama bulan dalam Bahasa Indonesia
-- Nama bulan dalam bahasa Indonesia
local nama_bulan = {
local monthsName = {
     [1] = "Januari",   [2] = "Februari", [3] = "Maret",   [4] = "April",
     "Januari", "Februari", "Maret", "April", "Mei", "Juni",
    [5] = "Mei",       [6] = "Juni",    [7] = "Juli",     [8] = "Agustus",
     "Juli", "Agustus", "September", "Oktober", "November", "Desember"
    [9] = "September", [10] = "Oktober", [11] = "November", [12] = "Desember"
}
}


-- Mengambil argumen dari template secara aman
-- Fungsi untuk menghitung selisih tahun secara presisi
local function get_args(frame)
local function calculateYears(bYear, bMonth, bDay)
     local args = {}
     local today = os.date("*t")
    if frame.getParent then
     local years = today.year - bYear
        local pargs = frame:getParent().args
      
        if pargs then
     if today.month < bMonth or (today.month == bMonth and today.day < bDay) then
            for k, v in pairs(pargs) do
                args[k] = mw.text.trim(tostring(v))
            end
        end
     end
    if frame.args then
        for k, v in pairs(frame.args) do
            args[k] = mw.text.trim(tostring(v))
        end
    end
    return args
end
 
-- Menghitung jumlah hari dalam suatu bulan
local function days_in_month(month, year)
     local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
     if month == 2 then
        if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then
            return 29
        end
    end
    return days[month] or 30
end
 
-- Algoritma presisi selisih waktu
local function calculate_age(y1, m1, d1, y2, m2, d2)
    local years = y2 - y1
    local months = m2 - m1
    local days = d2 - d1
 
    if days < 0 then
        months = months - 1
        local prev_month = m2 - 1
        local prev_year = y2
        if prev_month < 1 then
            prev_month = 12
            prev_year = prev_year - 1
        end
        days = days + days_in_month(prev_month, prev_year)
    end
 
    if months < 0 then
         years = years - 1
         years = years - 1
        months = months + 12
    end
    return years, months, days
end
-- Parsing input tanggal
local function parse_date(args)
    local y, m, d
    local input_str = args[1] or args["tanggal"] or args["date"]
    if input_str and input_str ~= "" then
        y, m, d = input_str:match("^([0-9]%d%d%d)%-([0-9]%d?)%-([0-9]%d?)$")
        if not y then
            y, m, d = input_str:match("^([0-9]%d%d%d)/([0-9]%d?)/([0-9]%d?)$")
        end
        if not y then
            y = input_str:match("^([0-9]%d%d%d)$")
            if y then m, d = 1, 1 end
        end
    end
    if not y and args[1] and args[1]:match("^%d+$") then
        y = tonumber(args[1])
        m = tonumber(args[2])
        d = tonumber(args[3])
     end
     end
 
      
    if not y and args["tahun"] then y = tonumber(args["tahun"]) end
     return years
    if not m and args["bulan"] then m = tonumber(args["bulan"]) end
     if not d and args["hari"] then d = tonumber(args["hari"]) end
 
     return tonumber(y), tonumber(m) or 1, tonumber(d) or 1
end
end


function p.utama(frame)
function p.main(frame)
     local args = get_args(frame)
     local args = frame:getParent().args
     local y1, m1, d1 = parse_date(args)
     local year, month, day


     if not y1 then
     -- Cek jika input menggunakan format YYYY-MM-DD atau YYYY/MM/DD
        return '<span class="error" style="color: #d33; font-weight: bold;">[Peringatan: Masukkan tanggal pendirian yang valid]</span>'
     local inputStr = args[1] or ""
    end
     if inputStr:find("^%d%d%d%d%-%d%d%-%d%d$") or inputStr:find("^%d%d%d%d/%d%d/%d%d$") then
 
        year, month, day = inputStr:match("(%d%d%d%d)[%-/](%d%d)[%-/](%d%d)")
     local now = os.date("!*t")
        year = tonumber(year)
     local y2 = tonumber(args["ref_tahun"]) or now.year
         month = tonumber(month)
    local m2 = tonumber(args["ref_bulan"]) or now.month
         day = tonumber(day)
    local d2 = tonumber(args["ref_hari"]) or now.day
 
    local is_future = false
    if y1 > y2 or (y1 == y2 and m1 > m2) or (y1 == y2 and m1 == m2 and d1 > d2) then
         is_future = true
    end
 
    local years, months, days
    if is_future then
         years, months, days = calculate_age(y2, m2, d2, y1, m1, d1)
     else
     else
         years, months, days = calculate_age(y1, m1, d1, y2, m2, d2)
         year = tonumber(args[1] or args.year)
        month = tonumber(args[2] or args.month)
        day = tonumber(args[3] or args.day)
     end
     end


     local mode = string.lower(args["mode"] or args["format"] or args["opsi"] or "otomatis")
     -- Validasi Tanggal
    local text_usia = ""
     if not year or not month or not day or month < 1 or month > 12 or day < 1 or day > 31 then
 
         return '<span style="color:red; font-weight:bold;">[Format Tanggal Salah]</span>'
     if years == 0 and months == 0 and days == 0 then
        text_usia = "hari ini"
    else
        if mode == "detail" or mode == "presisi" or mode == "lengkap" then
            local parts = {}
            if years > 0 then table.insert(parts, years .. " tahun") end
            if months > 0 then table.insert(parts, months .. " bulan") end
            if days > 0 then table.insert(parts, days .. " hari") end
            text_usia = table.concat(parts, ", ")
 
        elseif mode == "ringkas" or mode == "sederhana" then
            if years > 0 then
                text_usia = years .. " tahun"
            elseif months > 0 then
                text_usia = months .. " bulan"
            else
                text_usia = days .. " hari"
            end
 
        else
            if years >= 1 then
                if months > 0 then
                    text_usia = years .. " tahun, " .. months .. " bulan"
                else
                    text_usia = years .. " tahun"
                end
            elseif months >= 1 then
                if days > 0 then
                    text_usia = months .. " bulan, " .. days .. " hari"
                else
                    text_usia = months .. " bulan"
                end
            else
                text_usia = days .. " hari"
            end
        end
 
        if is_future then
            text_usia = "akan diluncurkan dalam " .. text_usia
        else
            text_usia = text_usia .. " yang lalu"
        end
    end
 
    local date_str = d1 .. " " .. (nama_bulan[m1] or "") .. " " .. y1
    local show_date = args["tampilkan_tanggal"] or args["show_date"] or "ya"
    local kurung = args["kurung"] or "ya"
    local output = ""
 
    if mode == "hanya_usia" or mode == "age_only" or show_date == "tidak" or show_date == "no" then
         if kurung == "ya" or kurung == "yes" then
            output = "(" .. text_usia .. ")"
        else
            output = text_usia
        end
    else
        if kurung == "ya" or kurung == "yes" then
            output = date_str .. ' <small class="explain" style="color: #555;">(' .. text_usia .. ')</small>'
        else
            output = date_str .. " — " .. text_usia
        end
     end
     end


     local auto_cat = args["kategori"] or args["cat"]
     local years = calculateYears(year, month, day)
     local jenis = string.lower(args["tipe"] or args["jenis"] or "organisasi")
     local monthName = monthsName[month] or ""


     if auto_cat == "ya" or auto_cat == "yes" then
     -- Teks durasi
        if jenis == "perusahaan" then
    local durationStr = string.format('%d tahun yang lalu', years)
            output = output .. "[[Kategori:Perusahaan yang didirikan tahun " .. y1 .. "]]"
        elseif jenis == "produk" then
            output = output .. "[[Kategori:Produk yang diluncurkan tahun " .. y1 .. "]]"
        elseif jenis == "papan" or jenis == "dewan" or jenis == "komite" then
            output = output .. "[[Kategori:Papan dan dewan yang dibentuk tahun " .. y1 .. "]]"
        else
            output = output .. "[[Kategori:Organisasi yang didirikan tahun " .. y1 .. "]]"
        end
    end


     return output
    -- Format Output Rapi:
    -- Baris 1: 29 November 1899
    -- Baris 2: (126 tahun yang lalu) -> Tegak normal, tidak miring, ukuran 80%
     return string.format('%d %s %d<br /><small style="font-size: 80%%;">(%s)</small>', day, monthName, year, durationStr)
end
end


return p
return p

Revisi terkini sejak 29 Oktober 2026 14.38

Module:Pendirian adalah modul mesin backend berbasis Lua yang menangani kalkulasi tanggal, waktu relatif, tahun kabisat, serta penyesuaian selisih waktu dinamis (Tahun, Bulan, Hari) untuk {{Pendirian}}.

Modul ini dibuat mandiri (standalone) tanpa ketergantungan pada modul eksternal seperti `Module:Arguments`, sehingga performanya sangat cepat, ringan, dan minim risiko bentrok pustaka.

`p.utama(frame)`

[sunting sumber]

Fungsi utama yang dipanggil oleh wikitext melalui "#invoke:Pendirian".

Fungsi ini menjalankan alur kerja berikut: 1. Parsing Argumen: Membaca parameter dari `frame` pemanggil atau `getParent()` (termasuk trimming otomatis untuk menghilangkan spasi berlebih). 2. Parsing Tanggal: Mendukung format input ISO (`YYYY-MM-DD`), format garis miring (`YYYY/MM/DD`), format tahun saja (`YYYY`), parameter terpisah berurutan (`YYYY|MM|DD`), maupun parameter nama (`tahun=`, `bulan=`, `hari=`). 3. Kalkulasi Selisih Waktu:

    • Menghitung selisih tahun, bulan, dan hari secara presisi.
    • Memeriksa dan memperhitungkan jumlah hari pada setiap bulan (28–31 hari).
    • Memperhitungkan tahun kabisat (pembagi 4, 100, dan 400).
    • Mengidentifikasi apakah tanggal yang dimasukkan berada di masa depan (rencana peluncuran) atau masa lalu.

4. Pengformatan Mode Output: Menyesuaikan hasil tampilan sesuai nilai parameter `mode`:

    • `otomatis` / `smart` (default): Menyesuaikan unit dominan secara otomatis.
    • `detail` / `presisi`: Menampilkan `X tahun, Y bulan, Z hari`.
    • `ringkas` / `sederhana`: Menampilkan unit tertinggi saja.
    • `hanya_usia`: Menampilkan teks usia tanpa menyertakan string tanggal pendirian.

5. Kategorisasi Otomatis: Menambahkan kategori wiki otomatis jika parameter `kategori=ya` diaktifkan.

Parameter Yang Didukung

[sunting sumber]
Parameter Tipe Deskripsi
`1`, `tanggal`, `date` String / Angka Input tanggal pendirian. Contoh: `2020-05-15`, `2020/05/15`, atau `2020`.
`2`, `bulan` Angka Bulan pendirian (jika menggunakan parameter terpisah). Contoh: `5`.
`3`, `hari` Angka Hari pendirian (jika menggunakan parameter terpisah). Contoh: `15`.
`mode`, `format`, `opsi` String Mengatur gaya tampilan output (`otomatis`, `detail`, `ringkas`, `hanya_usia`).
`tampilkan_tanggal`, `show_date` String Mengontrol tampilan tanggal awal (`ya` / `tidak`).
`kurung` String Memberikan pembungkus tanda kurung pada teks selisih waktu (`ya` / `tidak`).
`kategori`, `cat` String Mengaktifkan Kategori otomatis berdasarkan tahun pendirian (`ya` / `tidak`).
`tipe`, `jenis` String Jenis entitas untuk penentuan nama kategori (`organisasi`, `perusahaan`, `produk`, `papan`).
`ref_tahun`, `ref_bulan`, `ref_hari` Angka Parameter pengujian/overriding untuk mengubah tanggal acuan "saat ini" (default: server time UTC).

Penggunaan dari Modul Lua Lain

[sunting sumber]

Jika Anda ingin memanggil logika modul ini langsung dari modul Lua lainnya, Anda dapat meng-import modul dan memanggil fungsi `utama` dengan mengirimkan objek `frame` buatan:

local pendirian = require("Module:Pendirian")

-- Contoh simulasi panggilan frame
local res = pendirian.utama({
    getParent = function()
        return {
            args = {
                [1] = "2020-05-15",
                mode = "detail"
            }
        }
    end,
    args = {}
})

Struktur File Modul

[sunting sumber]

local p = {}

-- Nama bulan dalam bahasa Indonesia
local monthsName = {
    "Januari", "Februari", "Maret", "April", "Mei", "Juni",
    "Juli", "Agustus", "September", "Oktober", "November", "Desember"
}

-- Fungsi untuk menghitung selisih tahun secara presisi
local function calculateYears(bYear, bMonth, bDay)
    local today = os.date("*t")
    local years = today.year - bYear
    
    if today.month < bMonth or (today.month == bMonth and today.day < bDay) then
        years = years - 1
    end
    
    return years
end

function p.main(frame)
    local args = frame:getParent().args
    local year, month, day

    -- Cek jika input menggunakan format YYYY-MM-DD atau YYYY/MM/DD
    local inputStr = args[1] or ""
    if inputStr:find("^%d%d%d%d%-%d%d%-%d%d$") or inputStr:find("^%d%d%d%d/%d%d/%d%d$") then
        year, month, day = inputStr:match("(%d%d%d%d)[%-/](%d%d)[%-/](%d%d)")
        year = tonumber(year)
        month = tonumber(month)
        day = tonumber(day)
    else
        year = tonumber(args[1] or args.year)
        month = tonumber(args[2] or args.month)
        day = tonumber(args[3] or args.day)
    end

    -- Validasi Tanggal
    if not year or not month or not day or month < 1 or month > 12 or day < 1 or day > 31 then
        return '<span style="color:red; font-weight:bold;">[Format Tanggal Salah]</span>'
    end

    local years = calculateYears(year, month, day)
    local monthName = monthsName[month] or ""

    -- Teks durasi
    local durationStr = string.format('%d tahun yang lalu', years)

    -- Format Output Rapi:
    -- Baris 1: 29 November 1899
    -- Baris 2: (126 tahun yang lalu) -> Tegak normal, tidak miring, ukuran 80%
    return string.format('%d %s %d<br /><small style="font-size: 80%%;">(%s)</small>', day, monthName, year, durationStr)
end

return p