thai_holidays 0.1.0
thai_holidays: ^0.1.0 copied to clipboard
Pure-Dart Thai public-holiday calendar: fixed and movable Buddhist holidays, in-lieu days, special bridge days, and business-day helpers.
thai_holidays #
Pure-Dart Thai public-holiday calendar: fixed-date holidays, movable Buddhist holidays (Makha / Visakha / Asalha Bucha and Khao Phansa), the Royal Ploughing Ceremony, cabinet-announced special "bridge" days, stack-aware in-lieu (substitution) days, and business-day helpers.
Movable Buddhist dates are computed from the Thai lunisolar calendar via the
sibling package thai_lunar,
including the athikamat (double-eighth-month) leap-year shift.
All dates are UTC, date-only.
Features #
- Fixed-date holidays with historical effective-year gating (newer royal holidays are not emitted for years before they existed).
- Movable Buddhist holidays via
thai_lunar, including the athikamat leap-year month shift. - Cabinet-announced special ("bridge") holidays, seeded per year.
- Royal Ploughing Ceremony (announced annually, seeded for known years).
- Stack-aware in-lieu (substitution) days for holidays on a weekend.
- Stable, locale-independent
ThaiHolidayIdfor every holiday. - Government vs. bank distinction via a
bankHolidayflag. - Range and point queries:
holidayOn/holidaysOn/thaiHolidaysBetween. - Business-day helpers:
isBusinessDay,nextBusinessDay,addBusinessDays(negativensupported),businessDaysBetween.
Install #
dependencies:
thai_holidays: ^0.1.0
Usage #
import 'package:thai_holidays/thai_holidays.dart';
void main() {
// All public holidays in 2026 (a leap / athikamat year), sorted by date.
for (final h in thaiHolidays(2026)) {
print('${h.date.toIso8601String().substring(0, 10)} ${h.name(thai: false)}'
' [${h.type.name}] (id: ${h.id.name})');
}
// Identify a holiday without string-matching localized names.
final ny = holidayOn(DateTime.utc(2026, 1, 1));
print(ny?.id == ThaiHolidayId.newYear); // true
// All holidays on a date (dates can collide).
print(holidaysOn(DateTime.utc(2026, 7, 30)).length);
// Range query across a year boundary.
final boundary = thaiHolidaysBetween(
DateTime.utc(2025, 12, 28), DateTime.utc(2026, 1, 5));
print(boundary.length);
// Business-day helpers.
print(isBusinessDay(DateTime.utc(2026, 1, 1))); // false (holiday)
print(nextBusinessDay(DateTime.utc(2025, 12, 31))); // next working day
print(addBusinessDays(DateTime.utc(2026, 1, 5), 5)); // 5 business days on
print(businessDaysBetween(
DateTime.utc(2026, 1, 1), DateTime.utc(2026, 1, 31)));
}
Suppressing in-lieu days #
final core = thaiHolidays(2026, includeSubstitution: false);
API #
List<ThaiHoliday> thaiHolidays(int year, {bool includeSubstitution = true})List<ThaiHoliday> thaiHolidaysBetween(DateTime start, DateTime end, {bool includeSubstitution = true})— inclusive[start, end], across year boundariesbool isThaiHoliday(DateTime date)ThaiHoliday? holidayOn(DateTime date)— the holiday on a date, ornullList<ThaiHoliday> holidaysOn(DateTime date)— all holidays on a datebool isBusinessDay(DateTime date)DateTime nextBusinessDay(DateTime date)— strictly afterdateDateTime addBusinessDays(DateTime date, int n)—n < 0goes backwardint businessDaysBetween(DateTime a, DateTime b)— half-open(a, b], signedThaiHoliday(date,id,nameTh,nameEn,type,bankHoliday,observedFor) +name({bool thai = true})enum ThaiHolidayType { fixed, lunar, substitution, special }enum ThaiHolidayId { ... }— stable, locale-independent holiday identifier
Government vs. bank holidays #
The encoded set is the Royal Thai Government public-holiday list (cabinet
resolutions / Royal Gazette). Most entries are also Bank of Thailand (BOT)
bank holidays, but two are government holidays that banks do not observe —
Khao Phansa and the Royal Ploughing Ceremony. These carry
bankHoliday == false; an in-lieu day inherits the flag of the holiday it
observes. Filter with where((h) => h.bankHoliday) for the bank-holiday subset.
Supported range & data currency #
Accurate from ~2017 onward and current through 2026 for
annually-announced entries. Earlier years are approximate. Two data classes are
not rule-derivable and are maintained as per-year overlays in
lib/src/special.dart:
- Cabinet special ("bridge") holidays — announced ad hoc each year.
- Royal Ploughing Ceremony — its date is set annually by royal astrologers; only seeded for years with a confirmed date (others are omitted, not guessed).
See NOTICE.md for the seeded dates, sources, and effective-from years.
In-lieu (substitution) rule #
When a public holiday falls on a Saturday or Sunday, a compensatory holiday is
granted on the next working weekday that is not itself a holiday. The rule is
stack-aware: when several holidays fall on the same weekend (e.g. the three
consecutive Songkran days), each in-lieu day is pushed past the previously
allocated ones so they never collide. In-lieu entries have
type == ThaiHolidayType.substitution, observedFor set to the original
holiday's date, and the id of the holiday they observe.
Sources #
The holiday set and in-lieu rule follow Royal Thai Government cabinet
resolutions / Royal Gazette announcements (publicized by the PRD), cross-checked
against the vacanza/holidays Thailand provider. See NOTICE.md for per-date
citations. Lunar dates come from thai_lunar, a pure-Dart port of
pythaidate (MIT).
License #
MIT — see LICENSE.