Hướng dẫn làm lịch âm với JavaScript và thư viện solarLunar

Lịch âm dương là chức năng rất phổ biến trên các website tin tức, blog phong thủy, trang xem ngày. Với JavaScript, bạn hoàn toàn có thể tự xây dựng một lịch âm chạy trên trình duyệt mà không cần backend phức tạp. Bài viết này sẽ hướng dẫn từng bước cách nhúng thư viện solarLunar, chuyển đổi ngày dương sang ngày âm và hiển thị lịch tháng có kèm ngày âm.

Hướng dẫn làm lịch âm với JavaScript và thư viện solarLunar

1. Chuẩn bị thư viện solarLunar

solarLunar là thư viện JavaScript cung cấp hàm chuyển đổi giữa lịch dương và lịch âm Trung Hoa. Để dùng cho lịch âm Việt Nam cơ bản (hiển thị ngày, tháng, năm âm), thư viện này là đủ cho phần lõi tính toán.

Nhúng thư viện từ CDN:

<script src="https://unpkg.com/[email protected]/lib/solarlunar.min.js"></script>

2. Cấu trúc HTML tối giản cho lịch

Trước tiên cần một khung để hiển thị lịch. Ví dụ đơn giản theo dạng lịch tháng:

<div class="calendar-nav">
    <button id="prevMonth">Tháng trước</button>
    <span id="calendarTitle"></span>
    <button id="nextMonth">Tháng sau</button>
</div>

<div class="calendar-weekdays">
    <div>CN</div>
    <div>T2</div>
    <div>T3</div>
    <div>T4</div>
    <div>T5</div>
    <div>T6</div>
    <div>T7</div>
</div>

<div id="calendarGrid" class="calendar-grid"></div>

Lưới calendarGrid sẽ được JavaScript render từng ô ngày, mỗi ô gồm ngày dương và ngày âm.

3. Hàm chuyển đổi ngày dương sang ngày âm với solarLunar

solarLunarcung cấp hàm solar2lunar(year, month, day). Tháng được tính từ 1 đến 12, khác với JavaScript Date dùng 0 đến 11. Kết quả trả về là một object chứa thông tin năm, tháng, ngày âm cùng nhiều dữ liệu khác.

Ví dụ chuyển đổi một ngày cụ thể:

function chuyenDoiNgayDuongSangAm(year, month, day) {
    if (!window.solarlunar || !solarlunar.solar2lunar) {
        console.error("Thiếu thư viện solarlunar");
        return null;
    }

    // month: 1-12
    var lunar = solarlunar.solar2lunar(year, month, day);

    // lunar.lYear, lunar.lMonth, lunar.lDay
    console.log("Âm lịch:", lunar.lDay + "/" + lunar.lMonth + "/" + lunar.lYear);

    return lunar;
}

Từ hàm này, bạn có thể dùng lại trong logic render lịch để hiển thị ngày âm cho từng ô.

4. Render lịch tháng và gắn ngày âm

Bước tiếp theo là viết hàm tạo lịch tháng. Ý tưởng: tính ngày đầu tháng rơi vào thứ mấy, số ngày trong tháng, sau đó lặp 42 ô (6 hàng x 7 cột). Với mỗi ngày hợp lệ, gọi solar2lunar để lấy ngày âm.

var today = new Date();
var currentMonth = today.getMonth();     // 0-11
var currentYear  = today.getFullYear();  // ví dụ 2025

function renderCalendar(monthIndex, year) {
    var grid = document.getElementById("calendarGrid");
    var title = document.getElementById("calendarTitle");

    grid.innerHTML = "";
    title.textContent = "Tháng " + (monthIndex + 1) + " / " + year;

    var firstDay = new Date(year, monthIndex, 1).getDay(); // 0 = CN
    var daysInMonth = new Date(year, monthIndex + 1, 0).getDate();

    for (var i = 0; i < 42; i++) {
        var cell = document.createElement("div");
        cell.className = "calendar-cell";

        var dayNumber = i - firstDay + 1;

        if (dayNumber < 1 || dayNumber > daysInMonth) {
            cell.classList.add("calendar-empty");
            grid.appendChild(cell);
            continue;
        }

        // Tính âm lịch
        var lunar = solarlunar.solar2lunar(
            year,
            monthIndex + 1,
            dayNumber
        );

        var solarHtml = '<div class="day-solar">' + dayNumber + '</div>';
        var lunarHtml = '<div class="day-lunar">' + lunar.lDay + '</div>';

        cell.innerHTML = solarHtml + lunarHtml;

        grid.appendChild(cell);
    }
}

// Khởi tạo lần đầu
renderCalendar(currentMonth, currentYear);

Đoạn mã trên đã đủ để tạo một lịch tháng có hiển thị số âm ở góc dưới mỗi ô ngày.

5. Thêm nút chuyển tháng trước và tháng sau

Để lịch sử dụng thực tế, bạn nên thêm xử lý cho hai nút chuyển tháng. Logic rất đơn giản: thay đổi currentMonthcurrentYear, sau đó gọi lại renderCalendar.

document.getElementById("prevMonth").addEventListener("click", function () {
    currentMonth--;
    if (currentMonth < 0) {
        currentMonth = 11;
        currentYear--;
    }
    renderCalendar(currentMonth, currentYear);
});

document.getElementById("nextMonth").addEventListener("click", function () {
    currentMonth++;
    if (currentMonth > 11) {
        currentMonth = 0;
        currentYear++;
    }
    renderCalendar(currentMonth, currentYear);
});

Ngoài ra, bạn cũng có thể xử lý phím Enter hoặc input chọn tháng, năm để nhảy đến bất kỳ tháng nào mà vẫn tái sử dụng cùng một hàm render.

6. Gợi ý CSS cơ bản cho lịch âm

Để lịch dễ nhìn hơn, bạn nên dùng grid 7 cột và style riêng cho ngày dương, ngày âm, ô trống.

.calendar-weekdays,
.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
}

.calendar-weekdays > div {
    text-align: center;
    padding: 6px 0;
    font-weight: 600;
    font-size: 13px;
}

.calendar-grid {
    border-top: 1px solid #eee;
    border-left: 1px solid #eee;
}

.calendar-cell {
    border-right: 1px solid #eee;
    border-bottom: 1px solid #eee;
    padding: 6px 8px 10px;
    min-height: 70px;
    box-sizing: border-box;
}

.calendar-empty {
    background: #fafafa;
}

.day-solar {
    font-size: 15px;
    font-weight: 600;
}

.day-lunar {
    font-size: 12px;
    color: #888;
    margin-top: 2px;
}

Với đoạn CSS này, lịch âm sẽ hiển thị dưới dạng 7 cột, ngày dương nổi bật, ngày âm nhỏ hơn ở bên dưới nhưng vẫn dễ đọc.

CN
T2
T3
T4
T5
T6
T7

Tải về Xem demo

7. Mở rộng: sự kiện, click chi tiết, hỗ trợ mobile

Sau khi đã có lịch âm cơ bản, bạn có thể tiếp tục nâng cấp:

  • Gán sự kiện cho từng ngày (ví dụ Tết, Giáng Sinh) bằng cách định nghĩa mảng cấu hình rồi so khớp trong vòng lặp.
  • Thêm sự kiện click vào ô ngày để mở popup hiển thị đầy đủ ngày âm, ngày dương và mô tả sự kiện.
  • Hỗ trợ vuốt trái, vuốt phải trên mobile để chuyển tháng, giúp trải nghiệm giống ứng dụng native.
  • Kết hợp với localStorage để lưu tháng cuối cùng người dùng xem và tải lại đúng trạng thái đó.

8. Kết luận

Xây dựng một lịch âm với JavaScript không hề khó nếu bạn tách rõ hai phần: phần tính toán do thư viện solarLunar đảm nhiệm và phần hiển thị do bạn điều khiển bằng DOM và CSS. Chỉ với một vài hàm quan trọng như solar2lunar, vòng lặp sinh ô lịch và xử lý nút chuyển tháng, bạn đã có thể tạo ra một lịch âm dương đầy đủ cho website, sau đó phát triển thêm các tính năng nâng cao theo nhu cầu riêng.

Series: Âm lịch

Bình luận


2 bình luận
  • Hokage69th

    05/12/2025 lúc 10:50

    có thể cho mình source cái lịch này không?

    • Admin

      05/12/2025 lúc 11:00

      đã có link tải rồi đó bạn

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...