@lichta/core 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -15,22 +15,14 @@ interface SolarDate {
15
15
  month: number;
16
16
  year: number;
17
17
  }
18
+ /** Một lần xuất hiện Tiết Khí (Solar Term) trong năm dương lịch */
19
+ interface SolarTerm {
20
+ index: number;
21
+ name: string;
22
+ date: SolarDate;
23
+ jd: number;
24
+ }
18
25
 
19
- /**
20
- * Chuyển ngày Gregorian sang Julian Day Number.
21
- *
22
- * @param dd - Ngày (1-31)
23
- * @param mm - Tháng (1-12)
24
- * @param yy - Năm
25
- */
26
- declare function jdFromDate(dd: number, mm: number, yy: number): number;
27
- /**
28
- * Chuyển Julian Day Number sang ngày Gregorian.
29
- *
30
- * @param jd - Julian Day Number
31
- * @returns Tuple [day, month, year]
32
- */
33
- declare function jdToDate(jd: number): [number, number, number];
34
26
  declare class LichTa {
35
27
  /**
36
28
  * Chuyển đổi ngày Dương lịch sang Âm lịch.
@@ -72,6 +64,62 @@ declare class LichTa {
72
64
  static toSolar(lunarDay: number, lunarMonth: number, lunarYear: number, isLeap?: boolean, timeZone?: number): SolarDate;
73
65
  }
74
66
 
67
+ /**
68
+ * Thuật toán thiên văn nền tảng cho chuyển đổi Dương lịch ↔ Âm lịch Việt Nam
69
+ * Dựa trên công trình của Hồ Ngọc Đức (Đại học Leipzig)
70
+ * Tham khảo: Jean Meeus, "Astronomical Algorithms" (1998)
71
+ *
72
+ * Copyright (c) 2006 Ho Ngoc Duc. All Rights Reserved.
73
+ * TypeScript adaptation for Lichta library.
74
+ */
75
+ /**
76
+ * Chuyển ngày Gregorian sang Julian Day Number.
77
+ *
78
+ * @param dd - Ngày (1-31)
79
+ * @param mm - Tháng (1-12)
80
+ * @param yy - Năm
81
+ */
82
+ declare function jdFromDate(dd: number, mm: number, yy: number): number;
83
+ /**
84
+ * Chuyển Julian Day Number sang ngày Gregorian.
85
+ *
86
+ * @param jd - Julian Day Number
87
+ * @returns Tuple [day, month, year]
88
+ */
89
+ declare function jdToDate(jd: number): [number, number, number];
90
+
91
+ /** Một ô ngày trong lưới lịch tháng. */
92
+ interface CalendarDayCell {
93
+ solar: Date;
94
+ lunar: LunarDate;
95
+ isToday: boolean;
96
+ isSelected: boolean;
97
+ isCurrentMonth: boolean;
98
+ /** Số tuần trong năm (ISO-8601) của hàng chứa ô này — giống nhau cho cả 7 ô trong hàng. */
99
+ weekNumber: number;
100
+ }
101
+ /** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định, giống `Date.getDay()`), 1 = Thứ Hai. */
102
+ type FirstDayOfWeek = 0 | 1;
103
+ /**
104
+ * Tính số tuần theo chuẩn ISO-8601: tuần bắt đầu Thứ Hai, tuần 1 của năm là
105
+ * tuần chứa Thứ Năm đầu tiên (tương đương: tuần chứa ngày 4/1).
106
+ */
107
+ declare function getISOWeekNumber(date: Date): number;
108
+ /**
109
+ * Dựng lưới 42 ô (6 tuần x 7 ngày) cho 1 tháng dương lịch, gồm ngày tràn từ
110
+ * tháng trước/sau để lấp đầy tuần đầu/cuối, mỗi ô kèm ngày âm tương ứng.
111
+ *
112
+ * Logic này trước đây bị lặp lại độc lập ở Calendar.tsx/vue/svelte — tách ra
113
+ * đây để có 1 nguồn tính toán duy nhất (tránh 3 bản có thể lệch nhau khi sửa
114
+ * riêng lẻ), dùng chung cho cả Calendar và DatePicker ở mọi framework.
115
+ *
116
+ * @param month - Tháng dương lịch (1-12)
117
+ * @param year - Năm dương lịch
118
+ * @param selectedDate - Ngày đang được chọn (nếu có), dùng để đánh dấu `isSelected`
119
+ * @param firstDayOfWeek - Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai
120
+ */
121
+ declare function getCalendarGrid(month: number, year: number, selectedDate?: Date | null, firstDayOfWeek?: FirstDayOfWeek): CalendarDayCell[];
122
+
75
123
  /**
76
124
  * Internationalization — Hỗ trợ song ngữ Việt-Anh
77
125
  */
@@ -93,6 +141,10 @@ declare function t(locale: Locale): {
93
141
  readonly yearLabel: "Năm";
94
142
  readonly monthLabel: "Tháng";
95
143
  readonly destiny: "Mệnh";
144
+ readonly solarTermNames: readonly ["Xuân Phân", "Thanh Minh", "Cốc Vũ", "Lập Hạ", "Tiểu Mãn", "Mang Chủng", "Hạ Chí", "Tiểu Thử", "Đại Thử", "Lập Thu", "Xử Thử", "Bạch Lộ", "Thu Phân", "Hàn Lộ", "Sương Giáng", "Lập Đông", "Tiểu Tuyết", "Đại Tuyết", "Đông Chí", "Tiểu Hàn", "Đại Hàn", "Lập Xuân", "Vũ Thủy", "Kinh Trập"];
145
+ readonly trucNames: readonly ["Kiến", "Trừ", "Mãn", "Bình", "Định", "Chấp", "Phá", "Nguy", "Thành", "Thu", "Khai", "Bế"];
146
+ readonly elementRelationNames: readonly ["Tương sinh", "Được sinh", "Tương khắc", "Bị khắc", "Tương hòa"];
147
+ readonly trucQualityNames: readonly ["Xấu", "Trung bình", "Tốt"];
96
148
  } | {
97
149
  readonly heavenlyStems: readonly ["Giáp", "Ất", "Bính", "Đinh", "Mậu", "Kỷ", "Canh", "Tân", "Nhâm", "Quý"];
98
150
  readonly earthlyBranches: readonly ["Tý", "Sửu", "Dần", "Mão", "Thìn", "Tỵ", "Ngọ", "Mùi", "Thân", "Dậu", "Tuất", "Hợi"];
@@ -106,6 +158,10 @@ declare function t(locale: Locale): {
106
158
  readonly yearLabel: "Year";
107
159
  readonly monthLabel: "Month";
108
160
  readonly destiny: "Destiny";
161
+ readonly solarTermNames: readonly ["Spring Equinox", "Clear and Bright", "Grain Rain", "Start of Summer", "Grain Full", "Grain in Ear", "Summer Solstice", "Minor Heat", "Major Heat", "Start of Autumn", "End of Heat", "White Dew", "Autumn Equinox", "Cold Dew", "Frost's Descent", "Start of Winter", "Minor Snow", "Major Snow", "Winter Solstice", "Minor Cold", "Major Cold", "Start of Spring", "Rain Water", "Awakening of Insects"];
162
+ readonly trucNames: readonly ["Kiến", "Trừ", "Mãn", "Bình", "Định", "Chấp", "Phá", "Nguy", "Thành", "Thu", "Khai", "Bế"];
163
+ readonly elementRelationNames: readonly ["Generates", "Generated By", "Overcomes", "Overcome By", "Same Element"];
164
+ readonly trucQualityNames: readonly ["Bad", "Neutral", "Good"];
109
165
  } | {
110
166
  readonly heavenlyStems: readonly ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
111
167
  readonly earthlyBranches: readonly ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
@@ -119,6 +175,10 @@ declare function t(locale: Locale): {
119
175
  readonly yearLabel: "年";
120
176
  readonly monthLabel: "月";
121
177
  readonly destiny: "命";
178
+ readonly solarTermNames: readonly ["春分", "清明", "穀雨", "立夏", "小満", "芒種", "夏至", "小暑", "大暑", "立秋", "処暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒", "立春", "雨水", "啓蟄"];
179
+ readonly trucNames: readonly ["建", "除", "満", "平", "定", "執", "破", "危", "成", "収", "開", "閉"];
180
+ readonly elementRelationNames: readonly ["相生", "被生", "相克", "被克", "比和"];
181
+ readonly trucQualityNames: readonly ["凶", "普通", "吉"];
122
182
  } | {
123
183
  readonly heavenlyStems: readonly ["갑", "을", "병", "정", "무", "기", "경", "신", "임", "계"];
124
184
  readonly earthlyBranches: readonly ["자", "축", "인", "묘", "진", "사", "오", "미", "신", "유", "술", "해"];
@@ -132,6 +192,10 @@ declare function t(locale: Locale): {
132
192
  readonly yearLabel: "년";
133
193
  readonly monthLabel: "월";
134
194
  readonly destiny: "명";
195
+ readonly solarTermNames: readonly ["춘분", "청명", "곡우", "입하", "소만", "망종", "하지", "소서", "대서", "입추", "처서", "백로", "추분", "한로", "상강", "입동", "소설", "대설", "동지", "소한", "대한", "입춘", "우수", "경칩"];
196
+ readonly trucNames: readonly ["건", "제", "만", "평", "정", "집", "파", "위", "성", "수", "개", "폐"];
197
+ readonly elementRelationNames: readonly ["상생", "피생", "상극", "피극", "비화"];
198
+ readonly trucQualityNames: readonly ["흉", "보통", "길"];
135
199
  };
136
200
  /**
137
201
  * Lấy tên con giáp theo locale
@@ -139,32 +203,13 @@ declare function t(locale: Locale): {
139
203
  * @param locale - Ngôn ngữ
140
204
  */
141
205
  declare function getZodiacAnimal(branchIndex: number, locale?: Locale): string;
142
-
143
- /** Kết quả trả về của {@link getYearDetails}. */
144
- interface YearDetails {
145
- can: string;
146
- chi: string;
147
- menh: string;
148
- fullString: string;
149
- }
150
206
  /**
151
- * Lấy ra chuỗi tả toàn bộ Can, Chi Mệnh dựa vào số năm (Ví dụ: 2024)
152
- * Theo quy ước: Năm 4 (sau CN) là năm Giáp Tý (Can index 0, Chi index 0)
153
- *
154
- * Công thức Can Chi là chu kỳ 60 năm lặp lại vô hạn nên nhận mọi số năm nguyên,
155
- * kể cả năm 0 hoặc âm (trước Công Nguyên) — không giới hạn phạm vi như
156
- * {@link LichTa.toLunar} (phạm vi đó là do thuật toán tìm Điểm Sóc, không áp
157
- * dụng cho công thức Can Chi thuần).
158
- *
159
- * @param year - Năm (số nguyên bất kỳ, kể cả 0 hoặc âm)
160
- *
161
- * @example
162
- * ```typescript
163
- * getYearDetails(2024);
164
- * // → { can: 'Giáp', chi: 'Thìn', menh: 'Thủy', fullString: 'Giáp Thìn - Mệnh Thủy' }
165
- * ```
207
+ * Lấy nhãn thứ trong tuần theo locale, xoay vòng theo ngày bắt đầu tuần.
208
+ * @param locale - Ngôn ngữ
209
+ * @param firstDayOfWeek - Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai
166
210
  */
167
- declare function getYearDetails(year: number): YearDetails;
211
+ declare function getWeekDayLabels(locale: Locale, firstDayOfWeek?: FirstDayOfWeek): string[];
212
+
168
213
  /**
169
214
  * Tính Can Chi ngày từ Julian Day Number.
170
215
  *
@@ -205,6 +250,241 @@ declare function getMonthCanChi(lunarMonth: number, lunarYear: number, locale?:
205
250
  * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi', giữ nguyên hành vi cũ)
206
251
  */
207
252
  declare function getHourCanChi(hour: number, dayJd: number, locale?: Locale): string;
253
+
254
+ /**
255
+ * Lấy tên Ngũ Hành theo index và locale.
256
+ *
257
+ * @param index - Index Ngũ Hành (0-4, vào FIVE_ELEMENTS: Kim, Mộc, Thủy, Hỏa, Thổ)
258
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
259
+ */
260
+ declare function getElementName(index: number, locale?: Locale): string;
261
+ /**
262
+ * Tính index Ngũ Hành Nạp Âm (0-4, vào FIVE_ELEMENTS) của ngày, dùng chung bảng
263
+ * Nạp Âm 60 Hoa Giáp với `getYearDetails` (almanac.ts). Chỉ số Can/Chi tính giống hệt
264
+ * {@link import('./can-chi.js').getDayCanChi}.
265
+ *
266
+ * @param jd - Julian Day Number
267
+ */
268
+ declare function getDayElementIndex(jd: number): number;
269
+ /**
270
+ * Tính Mệnh (Ngũ Hành Nạp Âm) của ngày theo locale (xem {@link getDayElementIndex}).
271
+ *
272
+ * @param jd - Julian Day Number
273
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
274
+ */
275
+ declare function getDayElement(jd: number, locale?: Locale): string;
276
+ /**
277
+ * Tính index Ngũ Hành Nạp Âm (0-4, vào FIVE_ELEMENTS) của tháng âm lịch. Chỉ số
278
+ * Can/Chi tính giống hệt {@link import('./can-chi.js').getMonthCanChi}.
279
+ *
280
+ * @param lunarMonth - Tháng âm lịch (1-12)
281
+ * @param lunarYear - Năm âm lịch
282
+ */
283
+ declare function getMonthElementIndex(lunarMonth: number, lunarYear: number): number;
284
+ /**
285
+ * Tính Mệnh (Ngũ Hành Nạp Âm) của tháng âm lịch theo locale (xem {@link getMonthElementIndex}).
286
+ *
287
+ * @param lunarMonth - Tháng âm lịch (1-12)
288
+ * @param lunarYear - Năm âm lịch
289
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
290
+ */
291
+ declare function getMonthElement(lunarMonth: number, lunarYear: number, locale?: Locale): string;
292
+ /**
293
+ * Tính index Ngũ Hành Nạp Âm (0-4, vào FIVE_ELEMENTS) của giờ. Chỉ số Can/Chi tính
294
+ * giống hệt {@link import('./can-chi.js').getHourCanChi}.
295
+ *
296
+ * @param hour - Giờ (0-23)
297
+ * @param dayJd - Julian Day Number của ngày
298
+ */
299
+ declare function getHourElementIndex(hour: number, dayJd: number): number;
300
+ /**
301
+ * Tính Mệnh (Ngũ Hành Nạp Âm) của giờ theo locale (xem {@link getHourElementIndex}).
302
+ *
303
+ * @param hour - Giờ (0-23)
304
+ * @param dayJd - Julian Day Number của ngày
305
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
306
+ */
307
+ declare function getHourElement(hour: number, dayJd: number, locale?: Locale): string;
308
+ /**
309
+ * Tính quan hệ Ngũ Hành từ `fromIndex` tới `toIndex`, trả về index 0-4:
310
+ * 0 = sinh (from sinh to) 2 = khắc (from khắc to) 4 = hòa (cùng hành)
311
+ * 1 = được sinh (to sinh from) 3 = bị khắc (to khắc from)
312
+ *
313
+ * Với 5 hành, 2 hành khác nhau bất kỳ luôn rơi vào đúng 1 trong 4 quan hệ trên
314
+ * (mỗi hành có đúng 1 hành sinh nó, 1 hành nó sinh, 1 hành khắc nó, 1 hành nó khắc)
315
+ * — không có trường hợp mơ hồ.
316
+ *
317
+ * @param fromIndex - Index Ngũ Hành thứ nhất (0-4, vào FIVE_ELEMENTS)
318
+ * @param toIndex - Index Ngũ Hành thứ hai (0-4, vào FIVE_ELEMENTS)
319
+ */
320
+ declare function getElementRelationIndex(fromIndex: number, toIndex: number): number;
321
+ /**
322
+ * Lấy tên quan hệ Ngũ Hành giữa 2 hành theo locale (xem {@link getElementRelationIndex}).
323
+ *
324
+ * @param fromIndex - Index Ngũ Hành thứ nhất (0-4, vào FIVE_ELEMENTS)
325
+ * @param toIndex - Index Ngũ Hành thứ hai (0-4, vào FIVE_ELEMENTS)
326
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
327
+ *
328
+ * @example
329
+ * ```typescript
330
+ * // Mộc (1) và Hỏa (3): Mộc sinh Hỏa
331
+ * getElementRelation(1, 3); // → 'Tương sinh'
332
+ * getElementRelation(3, 1); // → 'Được sinh' (từ góc nhìn của Hỏa: được Mộc sinh)
333
+ * ```
334
+ */
335
+ declare function getElementRelation(fromIndex: number, toIndex: number, locale?: Locale): string;
336
+
337
+ /**
338
+ * Tính index Trực (0-11: Kiến, Trừ, Mãn, Bình, Định, Chấp, Phá, Nguy, Thành, Thu, Khai, Bế)
339
+ * tại một ngày dương lịch (Julian Day Number).
340
+ *
341
+ * Trực được neo theo 12 Tiết (Lập Xuân, Kinh Trập, Thanh Minh, ...) — tức các index
342
+ * lẻ trong 24 Tiết Khí ({@link import('./tiet-khi.js').getSolarTermsInYear}, `tiet-khi.ts`) —
343
+ * KHÔNG theo số tháng âm lịch, vì tháng nhuận âm lịch không tương ứng với một Tiết mới
344
+ * (dùng số tháng âm lịch sẽ cho kết quả sai trong các tháng nhuận).
345
+ *
346
+ * Ngày Tiết bắt đầu luôn là "Kiến" (index 0), Trực tăng dần 1 mỗi ngày sau đó và
347
+ * quay lại "Kiến" vào Tiết kế tiếp. Vì mỗi Tiết dài ~15 ngày (không chia hết cho
348
+ * chu kỳ 12 ngày của Trực), một số Trực sẽ bị lặp lại hoặc rút ngắn giữa 2 Tiết
349
+ * liên tiếp — đây là đặc tính vốn có của hệ Kiến Trừ truyền thống, không phải lỗi.
350
+ *
351
+ * Dùng `getSolarTermOccurrencesInYear` (dữ liệu thô, có cache theo năm+timeZone)
352
+ * thay vì `getSolarTermsInYear` công khai — tránh tính tên/locale không cần dùng
353
+ * tới, và tránh quét lại kinh độ Mặt Trời mỗi lần gọi khi hàm này được gọi lặp lại
354
+ * cho nhiều ngày cùng năm (vd. dựng lịch Trực cho cả tháng/năm).
355
+ *
356
+ * @param jd - Julian Day Number của ngày cần tra
357
+ * @param timeZone - Múi giờ (mặc định: 7 cho GMT+7 Việt Nam)
358
+ */
359
+ declare function getTrucIndex(jd: number, timeZone?: number): number;
360
+ /**
361
+ * Lấy tên Trực theo index và locale.
362
+ *
363
+ * @param index - Index Trực (0-11, xem {@link getTrucIndex})
364
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
365
+ */
366
+ declare function getTrucName(index: number, locale?: Locale): string;
367
+ /**
368
+ * Lấy tên Trực tại một ngày dương lịch (Julian Day Number).
369
+ *
370
+ * @param jd - Julian Day Number của ngày cần tra
371
+ * @param timeZone - Múi giờ (mặc định: 7 cho GMT+7 Việt Nam)
372
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
373
+ */
374
+ declare function getTruc(jd: number, timeZone?: number, locale?: Locale): string;
375
+ /**
376
+ * Lấy index mức tốt/xấu (0-2) của một Trực — xem giải thích độ tin cậy ở
377
+ * {@link TRUC_QUALITY_INDEX}.
378
+ *
379
+ * @param trucIndex - Index Trực (0-11, xem {@link getTrucIndex})
380
+ */
381
+ declare function getTrucQualityIndex(trucIndex: number): number;
382
+ /**
383
+ * Lấy tên mức tốt/xấu của một Trực theo locale (xem {@link getTrucQualityIndex}).
384
+ *
385
+ * @param trucIndex - Index Trực (0-11, xem {@link getTrucIndex})
386
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
387
+ */
388
+ declare function getTrucQuality(trucIndex: number, locale?: Locale): string;
389
+ /**
390
+ * Lấy Chi đối xung (Lục Xung) với một Chi cho trước — 2 Chi cách nhau đúng 6 vị
391
+ * trí trong vòng tròn 12 Chi: Tý-Ngọ, Sửu-Mùi, Dần-Thân, Mão-Dậu, Thìn-Tuất, Tỵ-Hợi.
392
+ *
393
+ * @param branchIndex - Index Địa Chi (0-11, vào EARTHLY_BRANCHES)
394
+ * @returns Index Địa Chi đối xung
395
+ */
396
+ declare function getXungBranchIndex(branchIndex: number): number;
397
+ /**
398
+ * Kiểm tra 2 Chi (tuổi) có phạm Lục Xung với nhau không.
399
+ *
400
+ * @param branchIndexA - Index Địa Chi thứ nhất (0-11)
401
+ * @param branchIndexB - Index Địa Chi thứ hai (0-11)
402
+ */
403
+ declare function isXung(branchIndexA: number, branchIndexB: number): boolean;
404
+ /**
405
+ * Lấy Chi bị Lục Hại với một Chi cho trước (xem {@link HAI_BRANCH_TARGET}).
406
+ *
407
+ * @param branchIndex - Index Địa Chi (0-11, vào EARTHLY_BRANCHES)
408
+ * @returns Index Địa Chi bị hại
409
+ */
410
+ declare function getHaiBranchIndex(branchIndex: number): number;
411
+ /**
412
+ * Kiểm tra 2 Chi (tuổi) có phạm Lục Hại với nhau không.
413
+ *
414
+ * @param branchIndexA - Index Địa Chi thứ nhất (0-11)
415
+ * @param branchIndexB - Index Địa Chi thứ hai (0-11)
416
+ */
417
+ declare function isHai(branchIndexA: number, branchIndexB: number): boolean;
418
+ /**
419
+ * Lấy nhóm Tứ Hành Xung (0-2) chứa một Chi cho trước.
420
+ *
421
+ * @param branchIndex - Index Địa Chi (0-11, vào EARTHLY_BRANCHES)
422
+ * @returns Index nhóm (0-2, xem {@link getTuHanhXungGroupMembers})
423
+ */
424
+ declare function getTuHanhXungGroupIndex(branchIndex: number): number;
425
+ /**
426
+ * Lấy 4 Chi thuộc cùng nhóm Tứ Hành Xung với một Chi cho trước (bao gồm cả chính nó).
427
+ *
428
+ * @param branchIndex - Index Địa Chi (0-11, vào EARTHLY_BRANCHES)
429
+ * @returns Mảng 4 index Địa Chi cùng nhóm
430
+ */
431
+ declare function getTuHanhXungGroupMembers(branchIndex: number): number[];
432
+ /**
433
+ * Kiểm tra 2 Chi (tuổi) khác nhau có cùng nhóm Tứ Hành Xung không.
434
+ *
435
+ * @param branchIndexA - Index Địa Chi thứ nhất (0-11)
436
+ * @param branchIndexB - Index Địa Chi thứ hai (0-11)
437
+ */
438
+ declare function isTuHanhXung(branchIndexA: number, branchIndexB: number): boolean;
439
+ /** Kết quả trả về của {@link getZodiacConflicts}. */
440
+ interface ZodiacConflicts {
441
+ xung: boolean;
442
+ hai: boolean;
443
+ tuHanhXung: boolean;
444
+ }
445
+ /**
446
+ * Kiểm tra toàn bộ quan hệ "kỵ tuổi" (Lục Xung, Lục Hại, Tứ Hành Xung) giữa 2 tuổi
447
+ * (Chi năm sinh). Không loại trừ lẫn nhau — 1 cặp Chi có thể vừa Lục Xung vừa cùng
448
+ * nhóm Tứ Hành Xung (vd. Tý-Ngọ là cả 2).
449
+ *
450
+ * @param branchIndexA - Index Địa Chi (con giáp) thứ nhất (0-11)
451
+ * @param branchIndexB - Index Địa Chi (con giáp) thứ hai (0-11)
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * getZodiacConflicts(0, 6); // Tý (0) và Ngọ (6)
456
+ * // → { xung: true, hai: false, tuHanhXung: true }
457
+ * ```
458
+ */
459
+ declare function getZodiacConflicts(branchIndexA: number, branchIndexB: number): ZodiacConflicts;
460
+
461
+ /** Kết quả trả về của {@link getYearDetails}. */
462
+ interface YearDetails {
463
+ can: string;
464
+ chi: string;
465
+ menh: string;
466
+ /** Index Ngũ Hành của `menh` (0-4, vào FIVE_ELEMENTS) — dùng cho `getElementRelation` (ngu-hanh.ts). */
467
+ menhIndex: number;
468
+ fullString: string;
469
+ }
470
+ /**
471
+ * Lấy ra chuỗi mô tả toàn bộ Can, Chi và Mệnh dựa vào số năm (Ví dụ: 2024)
472
+ * Theo quy ước: Năm 4 (sau CN) là năm Giáp Tý (Can index 0, Chi index 0)
473
+ *
474
+ * Công thức Can Chi là chu kỳ 60 năm lặp lại vô hạn nên nhận mọi số năm nguyên,
475
+ * kể cả năm 0 hoặc âm (trước Công Nguyên) — không giới hạn phạm vi như
476
+ * `LichTa.toLunar` (phạm vi đó là do thuật toán tìm Điểm Sóc, không áp
477
+ * dụng cho công thức Can Chi thuần).
478
+ *
479
+ * @param year - Năm (số nguyên bất kỳ, kể cả 0 hoặc âm)
480
+ *
481
+ * @example
482
+ * ```typescript
483
+ * getYearDetails(2024);
484
+ * // → { can: 'Giáp', chi: 'Thìn', menh: 'Hỏa', menhIndex: 3, fullString: 'Giáp Thìn - Mệnh Hỏa' }
485
+ * ```
486
+ */
487
+ declare function getYearDetails(year: number): YearDetails;
208
488
  /**
209
489
  * Lấy danh sách 6 giờ Hoàng Đạo trong ngày.
210
490
  * Giờ Hoàng Đạo phụ thuộc vào Địa Chi của ngày.
@@ -226,6 +506,65 @@ declare function getAuspiciousHours(dayJd: number, locale?: Locale): string[];
226
506
  * @returns Mảng 6 index Địa Chi (ví dụ: [0, 1, 3, 6, 7, 9])
227
507
  */
228
508
  declare function getAuspiciousHourIndices(dayJd: number): number[];
509
+ /**
510
+ * Lấy index (0-11, theo thứ tự Địa Chi Tý→Hợi) của 6 giờ Hắc Đạo (giờ xấu) trong
511
+ * ngày — phần bù của {@link getAuspiciousHourIndices} trong 12 canh giờ (6 giờ
512
+ * Hoàng Đạo + 6 giờ Hắc Đạo = đủ 12 canh).
513
+ *
514
+ * @param dayJd - Julian Day Number của ngày
515
+ * @returns Mảng 6 index Địa Chi, tăng dần
516
+ */
517
+ declare function getInauspiciousHourIndices(dayJd: number): number[];
518
+ /**
519
+ * Lấy danh sách 6 giờ Hắc Đạo (giờ xấu) trong ngày theo locale (xem
520
+ * {@link getInauspiciousHourIndices}).
521
+ *
522
+ * @param dayJd - Julian Day Number của ngày
523
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
524
+ * @returns Mảng 6 chuỗi tên Địa Chi
525
+ */
526
+ declare function getInauspiciousHours(dayJd: number, locale?: Locale): string[];
527
+
528
+ /**
529
+ * Lấy tên Tiết Khí theo index và locale.
530
+ *
531
+ * @param index - Index Tiết Khí (0-23, xem {@link getSolarTermIndex} trong astronomical.ts;
532
+ * 0 = Xuân Phân, 18 = Đông Chí, 21 = Lập Xuân, ...)
533
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
534
+ */
535
+ declare function getSolarTermName(index: number, locale?: Locale): string;
536
+ /**
537
+ * Lấy Tiết Khí đang hiệu lực tại một ngày dương lịch cho trước.
538
+ *
539
+ * `getSolarTermIndex` (astronomical.ts) trả về kinh độ Mặt Trời tại thời điểm 00:00 (đầu
540
+ * ngày) của `jdn`. Theo quy ước almanac truyền thống, một ngày được tính là "ngày
541
+ * Tiết Khí X" nếu thời điểm chuyển Tiết Khí rơi vào bất kỳ lúc nào trong ngày đó —
542
+ * tức là dùng giá trị tại 00:00 của ngày **kế tiếp** mới phản ánh đúng Tiết Khí đã
543
+ * "chốt" cho ngày hiện tại. Vì vậy hàm này tra cứu tại `jd + 1`, không phải `jd`.
544
+ *
545
+ * @param day - Ngày dương lịch (1-31)
546
+ * @param month - Tháng dương lịch (1-12)
547
+ * @param year - Năm dương lịch
548
+ * @param timeZone - Múi giờ (mặc định: 7 cho GMT+7 Việt Nam)
549
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
550
+ *
551
+ * @example
552
+ * ```typescript
553
+ * getSolarTerm(21, 6, 2024);
554
+ * // → { index: 6, name: 'Hạ Chí', date: { day: 21, month: 6, year: 2024 }, jd: ... }
555
+ * ```
556
+ */
557
+ declare function getSolarTerm(day: number, month: number, year: number, timeZone?: number, locale?: Locale): SolarTerm;
558
+ /**
559
+ * Liệt kê toàn bộ Tiết Khí bắt đầu trong một năm dương lịch (thường 24 hoặc 25 lần
560
+ * xuất hiện tùy năm, do các Tiết Khí không rơi đúng vào ranh giới năm).
561
+ *
562
+ * @param year - Năm dương lịch
563
+ * @param timeZone - Múi giờ (mặc định: 7 cho GMT+7 Việt Nam)
564
+ * @param locale - Ngôn ngữ hiển thị (mặc định: 'vi')
565
+ * @returns Mảng {@link SolarTerm} theo thứ tự thời gian tăng dần
566
+ */
567
+ declare function getSolarTermsInYear(year: number, timeZone?: number, locale?: Locale): SolarTerm[];
229
568
 
230
569
  /**
231
570
  * Lấy tên tháng âm lịch dạng chữ truyền thống.
@@ -302,26 +641,4 @@ declare function formatLunarDate(lunar: LunarDate, pattern: string, locale?: Loc
302
641
  */
303
642
  declare function formatTraditional(lunar: LunarDate): string;
304
643
 
305
- /** Một ô ngày trong lưới lịch tháng. */
306
- interface CalendarDayCell {
307
- solar: Date;
308
- lunar: LunarDate;
309
- isToday: boolean;
310
- isSelected: boolean;
311
- isCurrentMonth: boolean;
312
- }
313
- /**
314
- * Dựng lưới 42 ô (6 tuần x 7 ngày) cho 1 tháng dương lịch, gồm ngày tràn từ
315
- * tháng trước/sau để lấp đầy tuần đầu/cuối, mỗi ô kèm ngày âm tương ứng.
316
- *
317
- * Logic này trước đây bị lặp lại độc lập ở Calendar.tsx/vue/svelte — tách ra
318
- * đây để có 1 nguồn tính toán duy nhất (tránh 3 bản có thể lệch nhau khi sửa
319
- * riêng lẻ), dùng chung cho cả Calendar và DatePicker ở mọi framework.
320
- *
321
- * @param month - Tháng dương lịch (1-12)
322
- * @param year - Năm dương lịch
323
- * @param selectedDate - Ngày đang được chọn (nếu có), dùng để đánh dấu `isSelected`
324
- */
325
- declare function getCalendarGrid(month: number, year: number, selectedDate?: Date | null): CalendarDayCell[];
326
-
327
- export { type CalendarDayCell, LichTa, type Locale, type LunarDate, type SolarDate, type YearDetails, formatLunarDate, formatTraditional, getAuspiciousHourIndices, getAuspiciousHours, getCalendarGrid, getDayCanChi, getDayName, getHourCanChi, getMonthCanChi, getMonthName, getYearDetails, getZodiacAnimal, jdFromDate, jdToDate, t };
644
+ export { type CalendarDayCell, type FirstDayOfWeek, LichTa, type Locale, type LunarDate, type SolarDate, type SolarTerm, type YearDetails, type ZodiacConflicts, formatLunarDate, formatTraditional, getAuspiciousHourIndices, getAuspiciousHours, getCalendarGrid, getDayCanChi, getDayElement, getDayElementIndex, getDayName, getElementName, getElementRelation, getElementRelationIndex, getHaiBranchIndex, getHourCanChi, getHourElement, getHourElementIndex, getISOWeekNumber, getInauspiciousHourIndices, getInauspiciousHours, getMonthCanChi, getMonthElement, getMonthElementIndex, getMonthName, getSolarTerm, getSolarTermName, getSolarTermsInYear, getTruc, getTrucIndex, getTrucName, getTrucQuality, getTrucQualityIndex, getTuHanhXungGroupIndex, getTuHanhXungGroupMembers, getWeekDayLabels, getXungBranchIndex, getYearDetails, getZodiacAnimal, getZodiacConflicts, isHai, isTuHanhXung, isXung, jdFromDate, jdToDate, t };