Tài liệu LichTa

Hướng dẫn cài đặt và sử dụng thư viện LichTa trong dự án của bạn.

1. Cài đặt

Thư viện sử dụng cấu trúc Monorepo — mỗi package là một gói npm riêng biệt dưới scope @lichta/*. Cài package nào tùy vào nhu cầu, @lichta/core luôn được cài kèm tự động khi bạn cài bất kỳ package nào khác.

1.1. Module lõi (bắt buộc)

Đây là package duy nhất bắt buộc phải có — chứa toàn bộ logic tính toán, không phụ thuộc framework nào.

npm install @lichta/core
yarn add @lichta/core
pnpm add @lichta/core
bun add @lichta/core

1.2. Binding cho framework UI (tùy chọn)

Nếu bạn muốn dùng sẵn component Calendar/Formatter thay vì tự dựng UI, cài thêm package tương ứng với framework đang dùng:

# React
npm install @lichta/react

# Vue
npm install @lichta/vue

# Svelte 5 (re-export toàn bộ @lichta/core, không cần cài core riêng)
npm install @lichta/svelte

1.3. Adapter cho calendar library bên thứ 3 (tùy chọn)

Nếu bạn đang dùng FullCalendar, EventCalendar hoặc React Big Calendar và muốn tiêm (inject) ngày âm lịch vào lịch có sẵn:

npm install @lichta/full-calendar
npm install @lichta/event-calendar
npm install @lichta/react-big-calendar

2. Sử dụng cơ bản

Import LichTa từ module core để thực hiện các phép tính chuyển đổi ngày tháng cơ bản và tra cứu thông tin lịch.

import { LichTa } from '@lichta/core';

// 1. Dương lịch sang Âm lịch
const lunar = LichTa.toLunar(10, 2, 2024);
console.log(lunar);
// -> { day: 1, month: 1, year: 2024, isLeap: false, yearCanChi: 'Giáp Thìn' }

// 2. Chuyển đổi từ Date JavaScript hoặc ngày hôm nay
const fromJs = LichTa.fromDate(new Date());
const todayLunar = LichTa.today();

// 3. Âm lịch sang Dương lịch (isLeap = true nếu là tháng nhuận)
const solar = LichTa.toSolar(1, 1, 2024, false);
console.log(solar);
// -> { day: 10, month: 2, year: 2024 }

// 4. Tra cứu tháng nhuận và số ngày trong tháng âm lịch
LichTa.getLeapMonth(2023); // 2 (năm Quý Mão nhuận tháng 2)
LichTa.getDaysInLunarMonth(1, 2024); // 30 (tháng đủ 30 ngày, tháng thiếu 29 ngày)

// 5. Tùy chỉnh múi giờ (mặc định GMT+7 Việt Nam)
const lunarGmt8 = LichTa.toLunar(10, 2, 2024, 8);

toLunar/toSolar throw RangeError nếu ngày tháng năm nằm ngoài phạm vi hợp lệ (năm 1800–2199, tháng 1–12, ngày 1–31) hoặc nếu truyền isLeap = true vào năm không có tháng nhuận đó — nên bọc trong try/catch khi nhận input từ người dùng.

3. Số học & Thao tác Ngày Âm (Lunar Math)

Thực hiện các phép toán cộng trừ ngày, tính khoảng cách và so sánh giữa các ngày âm lịch. Hệ thống tự động xử lý chính xác các tháng thiếu (29 ngày), tháng đủ (30 ngày), tháng nhuận và chuyển năm.

import { LichTa, addDays, diffDays, isSameDay, isBefore, isAfter } from '@lichta/core';

const tet = LichTa.toLunar(10, 2, 2024); // Mùng 1 Tết Giáp Thìn (01/01/2024 Âm lịch)

// 1. Cộng / trừ ngày âm lịch
const mung2 = addDays(tet, 1); // 02/01/2024 Âm lịch
const tatNien = addDays(tet, -1); // 30/12/2023 Âm lịch (năm Quý Mão)

// 2. Tính khoảng cách số ngày giữa hai ngày âm lịch
const ramThangGieng = LichTa.toLunar(24, 2, 2024); // 15/01/2024 Âm lịch
diffDays(ramThangGieng, tet); // 14 (ngày)

// 3. So sánh thứ tự thời gian
isBefore(tet, ramThangGieng); // true
isAfter(tet, ramThangGieng); // false
isSameDay(tet, mung2); // false

4. Can Chi & Phong Thủy

Ngoài chuyển đổi ngày tháng, @lichta/core còn tính Can Chi, Ngũ Hành (Mệnh) và Ngày/Giờ Hoàng Đạo / Hắc Đạo.

import { LichTa, getYearDetails, getDayCanChi, getMonthCanChi, getHourCanChi, getAuspiciousHours, getInauspiciousHours, getAuspiciousDays } from '@lichta/core';

// Can Chi + Mệnh theo năm
getYearDetails(2024);
// -> { can: 'Giáp', chi: 'Thìn', menh: 'Hỏa', menhIndex: 3, fullString: 'Giáp Thìn - Mệnh Hỏa' }

// Can Chi ngày / tháng / giờ (cần Julian Day Number — lunar.jd)
const lunar = LichTa.toLunar(10, 2, 2024);
getDayCanChi(lunar.jd); // 'Giáp Thìn'
getMonthCanChi(lunar.month, lunar.year); // 'Bính Dần'
getHourCanChi(8, lunar.jd); // giờ Thìn (7h-9h)

// 6 Ngày Hoàng Đạo trong tháng và 6 Giờ Hoàng Đạo trong ngày
getAuspiciousDays(lunar.jd); // ['Tý', 'Sửu', 'Tỵ', 'Mùi'] ...
getAuspiciousHours(lunar.jd); // ['Tý', 'Mão', 'Thìn', 'Ngọ', 'Dậu', 'Tuất']
getInauspiciousHours(lunar.jd); // ['Sửu', 'Dần', 'Tỵ', 'Mùi', 'Thân', 'Hợi']

5. Tuổi Hợp — Xung (Tam Hợp & Lục Hợp)

Kiểm tra quan hệ tương hợp và tương xung giữa các Địa Chi (con giáp) theo ngũ hành sinh khắc: Tam Hợp (4 cục hợp), Lục Hợp (6 cặp nhị hợp), và Xung Khắc (Lục Xung, Lục Hại, Tứ Hành Xung). Tất cả đều nhận index Địa Chi (0–11, 0 = Tý).

import { isTamHop, getTamHopGroupMembers, isLucHop, getLucHopBranchIndex, isXung, isHai, isTuHanhXung, getZodiacHarmony, getZodiacConflicts, getZodiacRelations } from '@lichta/core';

// 1. Tam Hợp: Thân-Tý-Thìn (Thủy), Tỵ-Dậu-Sửu (Kim), Dần-Ngọ-Tuất (Hỏa), Hợi-Mão-Mùi (Mộc)
isTamHop(0, 4); // true — Tý (0) và Thìn (4)
getTamHopGroupMembers(0); // [0, 4, 8] — Tý, Thìn, Thân

// 2. Lục Hợp: Tý-Sửu, Dần-Hợi, Mão-Tuất, Thìn-Dậu, Tỵ-Thân, Ngọ-Mùi
isLucHop(0, 1); // true — Tý (0) và Sửu (1)
getLucHopBranchIndex(0); // 1 (Sửu)

// 3. Xung Khắc
isXung(0, 6); // true — Lục Xung: Tý - Ngọ
isHai(0, 7); // true — Lục Hại: Tý - Mùi
isTuHanhXung(0, 3); // true — Tứ Hành Xung: Tý - Mão

// 4. Tổng hợp quan hệ Hợp — Xung toàn diện
getZodiacHarmony(0, 4); // { tamHop: true, lucHop: false }
getZodiacConflicts(0, 6); // { xung: true, hai: false, tuHanhXung: true }
getZodiacRelations(0, 1); // { xung: false, hai: false, tuHanhXung: false, tamHop: false, lucHop: true }

6. Giờ Xuất Hành & Ngày Kỵ Dân Gian

Phương pháp chọn giờ xuất hành Lý Thuần Phong (Lục Nhâm tiểu độn) và hệ thống tra cứu ngày đại kỵ dân gian theo Ngọc Hạp Thông Thư & Lịch Vạn Niên.

import { LichTa, getLyThuanPhongHour, getAllLyThuanPhongHoursOfDay, getDayTaboos, isTamNuong, isNguyetKy, isDuongCongKyNhat } from '@lichta/core';

// 1. Giờ xuất hành Lý Thuần Phong (Đại An, Lưu Niên, Tốc Hỷ, Xích Khẩu, Tiểu Cát, Không Vong)
const hour8 = getLyThuanPhongHour(1, 1, 8); // 8h sáng Mùng 1 Tết
// -> { index: 4, name: 'Tiểu Cát', isAuspicious: true, branchIndex: 4, branchName: 'Thìn' }

// Danh sách toàn bộ 12 canh giờ trong ngày
const allHours = getAllLyThuanPhongHoursOfDay(1, 1);

// 2. Ngày Kỵ Dân Gian (Tam Nương, Nguyệt Kỵ, Dương Công Kỵ Nhật, Sát Chủ, Thọ Tử, Vãng Vong)
const lunarMung5 = LichTa.toLunar(14, 2, 2024); // Mùng 5 tháng Giêng
const taboos = getDayTaboos(lunarMung5);
// -> { isTamNuong: false, isNguyetKy: true, ..., hasTaboo: true, tabooNames: ['Nguyệt Kỵ'] }

// Kiểm tra từng loại ngày kỵ cụ thể
isTamNuong(3); // true — mùng 3, 7, 13, 18, 22, 27
isNguyetKy(5); // true — mùng 5, 14, 23
isDuongCongKyNhat(13, 1); // true — 13 ngày Dương Công Kỵ Nhật

7. Ngũ Hành, Tiết Khí, Trực & Thần Sát

@lichta/core tính toán Ngũ Hành (Mệnh Nạp Âm + Tương Sinh Tương Khắc), 24 Tiết Khí, Trực (12 Kiến Trừ), Thần Sát và Hướng Xuất Hành.

import { getDayElement, getSolarTerm, getTruc, getDayThanSat, getDepartureDirections } from '@lichta/core';

// Ngũ Hành Nạp Âm của ngày — dùng chung bảng Nạp Âm 60 Hoa Giáp với getYearDetails()
getDayElement(lunar.jd); // 'Hỏa'

// Tiết Khí đang hiệu lực tại 1 ngày, hoặc liệt kê cả 24 Tiết Khí trong năm
getSolarTerm(21, 6, 2024);
// -> { index: 6, name: 'Hạ Chí', date: { day: 21, month: 6, year: 2024 }, jd: 2460483 }

// Trực (12 Kiến Trừ) — neo theo Tiết, đúng cả trong tháng nhuận
getTruc(lunar.jd); // 'Phá'

// Thần Sát (Hoàng Đạo / Hắc Đạo: Thanh Long, Minh Đường...) và Hướng Xuất Hành (Hỷ Thần, Tài Thần)
getDayThanSat(lunar.jd); // { name: 'Thanh Long', fullName: 'Thanh Long Hoàng Đạo', isAuspicious: true }
getDepartureDirections(lunar.jd); // { hyThan: 'Đông Bắc', taiThan: 'Đông Nam' }

Chi tiết đầy đủ (Mệnh cho tháng/giờ, index thuần túy không phụ thuộc locale, tương sinh tương khắc...): xem API Reference.

8. Format & Parse (Định dạng & Phân tích)

Các hàm tiện ích để hiển thị ngày âm lịch theo kiểu truyền thống Việt Nam, theo pattern tùy chỉnh, hoặc phân tích chuỗi ngày âm lịch.

import { formatTraditional, formatLunarDate, parseLunarDate, getMonthName, getDayName } from '@lichta/core';

// 1. Format truyền thống Việt Nam
formatTraditional(lunar);
// -> 'Mùng Một tháng Giêng năm Giáp Thìn'

// 2. Format theo pattern tùy biến
formatLunarDate(lunar, 'dd/MM/yyyy'); // '01/01/2024'
formatLunarDate(lunar, 'Ngày DC'); // 'Ngày Giáp Thìn'

// 3. Phân tích chuỗi ngày âm lịch thành LunarDate (hỗ trợ cả tháng nhuận L)
const parsed = parseLunarDate('15/08/2024', 'dd/MM/yyyy');
// -> { day: 15, month: 8, year: 2024, isLeap: false, ... }

const leapParsed = parseLunarDate('15/02/2023 Nhuận', 'dd/MM/yyyy L');
// -> { day: 15, month: 2, year: 2023, isLeap: true, ... }
TokenMô tảVí dụ
dd / dNgày (2 chữ số / không)01, 15
MM / MTháng (2 chữ số / không)01, 12
yyyy / yyNăm (4 chữ số / 2 chữ số)2024, 24
CC / MC / DCCan Chi năm / tháng / ngàyGiáp Thìn
L"Nhuận" nếu là tháng nhuậnNhuận

9. Components & Frameworks

Mỗi package @lichta/react, @lichta/vue, @lichta/svelte export sẵn component Calendar (lịch tháng có ngày âm lịch) đóng gói trên @lichta/core.

React

import { Calendar } from '@lichta/react';

<Calendar
  theme="glass"
  locale="vi"
  firstDayOfWeek={1} // tuần bắt đầu Thứ Hai
  showWeekNumber // hiện số tuần ISO-8601
  onSelect={(date, lunar) => console.log(date, lunar)}
  renderDay={(cell) => ...}
/>

Vue

<script setup>
import { Calendar } from '@lichta/vue';
</script>

<Calendar theme="glass" locale="vi" @select="onSelect" />

Vue phát sự kiện chọn ngày qua @select (chưa hỗ trợ prop render tùy chỉnh như React/Svelte).

Svelte 5

<script>
  import { Calendar } from '@lichta/svelte';
</script>

<Calendar theme="glass" locale="vi" onSelect={(date, lunar) => ...} />

@lichta/svelte re-export toàn bộ API của @lichta/core luôn, không cần cài @lichta/core riêng.

PropKiểuMô tả
month / yearnumberTháng/năm hiển thị (đồng bộ lại nếu prop đổi từ component cha)
selectedDateDate | nullNgày được chọn — controlled nếu truyền, uncontrolled (tự quản lý) nếu bỏ qua
showLunarbooleanHiện ngày âm lịch dưới ngày dương (mặc định true)
locale'vi' | 'en' | 'ja' | 'ko'Ngôn ngữ nhãn thứ trong tuần
firstDayOfWeek0 | 1Ngày bắt đầu tuần — 0 = Chủ Nhật (mặc định), 1 = Thứ Hai
showWeekNumberbooleanHiện số tuần (ISO-8601) ở đầu mỗi hàng (mặc định false)
theme'classic' | 'glass'Giao diện lịch

DatePicker

Mỗi package cũng export component DatePicker (input + popover chọn ngày). DatePicker không tái sử dụng UI của Calendar — nó dựng lưới lịch riêng, gọn và nhẹ hơn, phù hợp cho form nhập liệu thay vì lịch xem toàn tháng.

import { DatePicker } from '@lichta/react';
import '@lichta/core/styles/datepicker-base.css';

<DatePicker
  theme="glass"
  locale="vi"
  onSelect={(date, lunar) => console.log(date, lunar)}
/>
<script setup>
import { DatePicker } from '@lichta/vue';
</script>

<DatePicker theme="glass" locale="vi" @select="onSelect" />
<script>
  import { DatePicker } from '@lichta/svelte';
</script>

<DatePicker theme="glass" locale="vi" onSelect={(date, lunar) => ...} />
PropKiểuMô tả
valueDate | nullNgày đang chọn — component tự đồng bộ khi prop đổi từ bên ngoài
placeholderstringPlaceholder khi chưa chọn ngày (mặc định 'Chọn ngày')
showLunarbooleanHiện ngày âm lịch trong popover (mặc định true)
locale'vi' | 'en' | 'ja' | 'ko'Ngôn ngữ hiển thị trong popover
theme'classic' | 'glass'Giao diện input + popover
format(date: Date) => stringHàm format ngày hiển thị trên input (mặc định dd/MM/yyyy)
disabledbooleanVô hiệu hoá input

Popover tự đóng khi: chọn xong 1 ngày, click ra ngoài, hoặc nhấn phím Escape. Xem demo trực tiếp từng framework ở trang chủ, mục "Dùng thử demo trực tiếp".

10. Tích hợp Calendar bên thứ 3

Các package @lichta/full-calendar, @lichta/event-calendar, @lichta/react-big-calendar export một hàm duy nhất: injectLunarDates(options, pluginOptions?) — bọc cấu hình gốc của calendar library và tiêm ngày âm lịch vào từng ô ngày.

import { Calendar } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import { injectLunarDates } from '@lichta/full-calendar';

const calendar = new Calendar(el, injectLunarDates({
  plugins: [dayGridPlugin],
  initialView: 'dayGridMonth'
}, { showLeapMonth: true, color: '#81b29a' }));
pluginOptionsMặc địnhMô tả
showLeapMonthtrueHiện chữ "(Nhuận)" cho tháng nhuận
showTooltiptrueHiện Can Chi khi hover
monthOnFirstDayOnlyfalseChỉ hiện số tháng âm vào mùng 1
color / className'#888'Tùy chỉnh màu chữ / class CSS
render—Hàm render HTML/React node tùy chỉnh, nhận vào LunarDate

Lưu ý: @lichta/event-calendar dùng runtime Svelte 4 nội bộ — không tương thích trực tiếp trong ứng dụng Svelte 5 (chỉ dùng ngoài Svelte 5 hoặc Vanilla JS).

11. Tài liệu API

Đây là tài liệu hướng dẫn sử dụng ở mức tổng quan. Để tra cứu đầy đủ chữ ký hàm, kiểu dữ liệu, và toàn bộ hàm tiện ích khác của @lichta/core, xem trang tham chiếu API chi tiết.

Xem tài liệu API đầy đủ