kenat 1.0.0 copy "kenat: ^1.0.0" to clipboard
kenat: ^1.0.0 copied to clipboard

A comprehensive Ethiopian calendar library for Dart with full support for date conversions, holidays, fasting periods, Bahire Hasab, Geez numerals, and traditional calendar features.

Kenat โ€” Ethiopian Calendar for Dart ๐Ÿ—“๏ธ #

pub package Dart License: MIT

Kenat (แ‰€แŠ“แ‰ต โ€” "days" in Amharic) is a comprehensive pure-Dart library for the Ethiopian calendar system. It provides everything you need to work with Ethiopian dates, times, and cultural/religious data in your Dart or Flutter application.


โœจ Features #

  • ๐Ÿ”„ Date Conversions โ€” Seamless Ethiopian โ†” Gregorian conversions
  • ๐Ÿ“… Date Arithmetic โ€” Add/subtract days, months, and years; compute differences
  • ๐Ÿ•Œ๐Ÿ• Holidays โ€” Fixed public holidays, movable Christian feasts, and Islamic holidays (Eid, Moulid)
  • ๐Ÿ™ Fasting Periods โ€” Abiy Tsome, Nineveh, Filseta, Tsome Hawaryat, Tsome Dihenet, Ramadan
  • ๐Ÿ“– Bahire Hasab โ€” Full Ethiopian ecclesiastical computation system for movable feasts
  • โฐ Ethiopian Time โ€” 12-hour day/night period system with Gregorian conversion
  • ๐Ÿ”ข Geez Numerals โ€” Convert Arabic โ†” Ethiopic (Geez) numerals
  • ๐Ÿ—“๏ธ Calendar Grid โ€” Generate month grids with holiday and saint data overlays
  • ๐Ÿ›๏ธ Orthodox Saints โ€” Comprehensive hagiography data for all 13 months
  • ๐ŸŒ Multilingual โ€” Amharic and English support throughout the API
  • โš ๏ธ Error Handling โ€” Descriptive, typed error classes for all failure modes

๐Ÿ“ฆ Installation #

Add to your pubspec.yaml:

dependencies:
  kenat: ^1.0.0

Then run:

dart pub get

๐Ÿš€ Quick Start #

import 'package:kenat/kenat.dart';

void main() {
  // Today's Ethiopian date
  final today = Kenat.now();
  print(today.formatStandard());           // e.g. "แŒแŠ•แ‰ฆแ‰ต 27 2016"
  print(today.formatStandard('english'));  // e.g. "Ginbot 27 2016"

  // Create from Ethiopian date
  final eth = Kenat.fromEthiopian(2016, 1, 1);
  print(eth.getGregorian());  // {year: 2023, month: 9, day: 11}

  // Create from Gregorian date
  final greg = Kenat.fromGregorian(2024, 5, 23);
  print(greg.getEthiopian()); // {year: 2016, month: 9, day: 15}
}

๐Ÿ“– API Reference #

Kenat โ€” The Main Class #

The primary class for all calendar operations. Can be constructed from a DateTime, an Ethiopian date map, or a date string.

Constructors & Factories

Kenat.now()                                      // Current date
Kenat.fromEthiopian(int year, int month, int day)
Kenat.fromGregorian(int year, int month, int day)
Kenat.fromString('2016/9/15')                    // "yyyy/mm/dd" or "yyyy-mm-dd"

Date Access

final d = Kenat.fromEthiopian(2016, 9, 15);

d.getEthiopian();  // {year: 2016, month: 9, day: 15}
d.getGregorian();  // {year: 2024, month: 5, day: 23}
d.getWeekday();    // 4  (0=Sunday โ€ฆ 6=Saturday)
d.getWeekdayName();         // "แˆแˆ™แˆต" (Amharic)
d.getWeekdayName('english'); // "Thursday"
d.getDaysInMonth();  // 30
d.getDayOfYear();    // day number within the Ethiopian year
d.isLeapYear();      // false
d.isToday;           // bool
d.isWeekend;         // bool

Formatting

d.formatStandard();            // "แŒแŠ•แ‰ฆแ‰ต 15 2016"
d.formatStandard('english');   // "Ginbot 15 2016"
d.formatInGeez();              // "แŒแŠ•แ‰ฆแ‰ต แฒแญ แณแปแฒแฎ"
d.formatWithWeekday();         // "แˆแˆ™แˆต, แŒแŠ•แ‰ฆแ‰ต 15 2016"
d.formatWithWeekday('english', true); // with Geez numerals
d.formatShort();               // "2016/09/15"
d.toISODateString();           // "2016-09-15"

Date Arithmetic

d.addDays(10);      // new Kenat 10 days later
d.addMonths(2);     // 2 months later
d.addYears(1);      // 1 year later

d.add(5, 'days');      // generic add
d.subtract(3, 'months');

d.diffInDays(other);    // int
d.diffInMonths(other);  // int
d.diffInYears(other);   // int
d.diffBreakdown(other); // {years, months, days}

Date Comparison

d.isBefore(other);  // bool
d.isAfter(other);   // bool
d.isSameDay(other); // bool
d == other;         // equality by date
d.startOf('month');   // first day of month
d.startOf('day');     // same day, time set to 1:00 day
d.endOf('month');     // last day of month
d.endOf('day');       // same day, time set to 12:00 night
d.startOfMonth();     // convenience alias
d.endOfMonth();       // convenience alias

Holidays #

// Get a specific holiday for a year
final meskel = getHoliday('meskel', 2016);
// {key: 'meskel', name: 'แˆ˜แˆตแ‰€แˆ', ethiopian: {year: 2016, month: 1, day: 17}, ...}

// All holidays in a month
final holidays = getHolidaysInMonth(2016, 1);
// Optional language option
final holidaysEn = getHolidaysInMonth(2016, 1, {'lang': 'english'});

// Filter by tag
final publicHolidays = getHolidaysInMonth(2016, 1, {'filter': 'public'});
final christianOnly = getHolidaysInMonth(2016, 1, {'filter': 'christian'});
final islamicOnly   = getHolidaysInMonth(2016, 1, {'filter': 'muslim'});

// All holidays for a year
final yearHolidays = getHolidaysForYear(2016);

Holiday keys: enkutatash, meskel, gena, timket, adwa, labour, patriots, martyrsDay, beherbehereseb, nineveh, abiyTsome, debreZeit, hosanna, siklet, fasika, rikbeKahnat, erget, paraclete, tsomeHawaryat, tsomeDihnet, eidFitr, eidAdha, moulid

Holiday tags: public, state, religious, christian, orthodox, muslim, cultural


Bahire Hasab #

The Bahire Hasab is the Ethiopian Orthodox system for computing movable feasts.

final bh = getBahireHasab(2016);

print(bh['ameteAlem']);     // Age of the world (e.g. 7516)
print(bh['evangelist']);    // {name: 'แ‹ฎแˆแŠ•แˆต', remainder: 3}
print(bh['newYear']);       // {dayName: 'แ‰…แ‹ณแˆœ', tinteQemer: 5}
print(bh['medeb']);         // Metonic cycle position
print(bh['nineveh']);       // {year: 2016, month: 5, day: 17}
print(bh['movableFeasts']); // Map of all movable feasts

// Get a single movable holiday
final fasika = getMovableHoliday('fasika', 2016);
// {year: 2016, month: 8, day: 27}

Movable feast keys: nineveh, abiyTsome, debreZeit, hosanna, siklet, fasika, rikbeKahnat, erget, paraclete, tsomeHawaryat, tsomeDihnet


Fasting Periods #

import 'package:kenat/kenat.dart';

// Get start and end dates of a fasting period
final period = getFastingPeriod(FastingKeys.abiyTsome, 2016);
// {start: {year:2016, month:6, day:4}, end: {year:2016, month:8, day:26}}

// Get full fasting info with name and description
final info = getFastingInfo(FastingKeys.filseta, 2016, {'lang': 'english'});
// {key: 'filseta', name: 'Filseta', description: '...', tags: [...], period: {...}}

// Check if a date is an Orthodox weekly fast day (Wed/Fri, excluding post-Easter period)
final isfast = isTsomeDihnetFastDay({'year': 2016, 'month': 1, 'day': 5});
// true or false

Fasting keys (via FastingKeys class):

Key Description
FastingKeys.abiyTsome Lent (Great Fast)
FastingKeys.nineveh Fast of Nineveh
FastingKeys.tsomeNebiyat Fast of the Prophets
FastingKeys.filseta Fast of the Assumption (Nehase 1โ€“14)
FastingKeys.tsomeHawaryat Fast of the Apostles
FastingKeys.tsomeDihenet Weekly fasting (Wed & Fri)
FastingKeys.ramadan Islamic Ramadan

Ethiopian Time (Time) #

The Ethiopian time system uses a 12-hour clock shifted by 6 hours from the Gregorian clock (6 AM = 12:00 "day", 6 PM = 12:00 "night").

// Create from Ethiopian hour/minute/period
final t = Time(6, 30, 'day');        // 6:30 AM Ethiopian = 12:30 PM Gregorian

// Create from Gregorian 24h time
final t2 = Time.fromGregorian(14, 0); // 2:00 PM = 8:00 "day" Ethiopian

// Create from string
final t3 = Time.fromString('6:30 night'); // or "แฎ:แด แˆ›แ‰ณ"

// Convert back to Gregorian
print(t.toGregorian()); // {hour: 12, minute: 30}

// Format
print(t.format());                          // "แฎ:แด แŒ แ‹‹แ‰ต"
print(t.format({'useGeez': false}));        // "06:30 day"
print(t.format({'lang': 'english'}));       // "06:30 day"

// Arithmetic
final later = t.add({'hours': 2, 'minutes': 30});
final earlier = t.subtract({'hours': 1});
final difference = t.diff(t2); // {hours: 1, minutes: 30}

// Kenat with time
final d = Kenat.fromEthiopian(2016, 9, 15);
final withTime = d.setTime(6, 30, 'day');
print(withTime.formatWithTime()); // "แŒแŠ•แ‰ฆแ‰ต 15 2016 06:30 แŒ แ‹‹แ‰ต"

Geez (Ethiopic) Numerals #

toGeez(15);      // "แฒแญ"
toGeez(2016);    // "แณแปแฒแฎ"
toGeez(10000);   // "แผ"

toArabic('แฒแญ');   // 15
toArabic('แณแปแฒแฎ'); // 2016

Calendar Month Grid #

Generate a structured calendar grid for UI rendering, with optional holidays, saints, and Geez numeral support.

final grid = createMonthGrid({
  'year': 2016,
  'month': 9,
  'useGeez': false,
  'weekdayLang': 'amharic', // or 'english'
  'weekStart': 0,           // 0=Sunday, 1=Monday, ...
  'mode': 'public',         // 'public' | 'christian' | 'orthodox' | 'muslim'
});

print(grid['monthName']); // "แŒแŠ•แ‰ฆแ‰ต"
print(grid['year']);      // "2016"
print(grid['headers']);   // ["แŠฅแˆ‘แ‹ต","แˆฐแŠž","แˆ›แŠญแˆฐแŠž",...]

// Each entry in grid['days'] is either null (padding) or:
// {
//   ethiopian: {year, month, day},
//   gregorian: {year, month, day},
//   weekday: 4,
//   weekdayName: "แˆแˆ™แˆต",
//   isToday: false,
//   holidays: [ {key, name, description, tags, ...} ]
// }

// Navigate months
final nextMonth = grid['up']();
final prevMonth = grid['down']();

Standalone Utility Functions #

All major operations are also available as top-level functions for convenience:

// Conversions
toEC(2024, 5, 23);  // Ethiopian: {year: 2016, month: 9, day: 15}
toGC(2016, 9, 15);  // Gregorian: {year: 2024, month: 5, day: 23}

// Date arithmetic
addDays({'year': 2016, 'month': 1, 'day': 1}, 10);
addMonths({'year': 2016, 'month': 1, 'day': 1}, 2);
addYears({'year': 2016, 'month': 1, 'day': 1}, 1);
diffInDays(date1, date2);
diffInMonths(date1, date2);
diffInYears(date1, date2);

// Calendar grid
createMonthGrid({'year': 2016, 'month': 9});

// Format
formatStandard({'year': 2016, 'month': 9, 'day': 15});         // "แŒแŠ•แ‰ฆแ‰ต 15 2016"
formatInGeezAmharic({'year': 2016, 'month': 9, 'day': 15});   // "แŒแŠ•แ‰ฆแ‰ต แฒแญ แณแปแฒแฎ"
formatShort({'year': 2016, 'month': 9, 'day': 15});           // "2016/09/15"
formatWithWeekday({'year': 2016, 'month': 9, 'day': 15});

๐Ÿ—บ๏ธ Ethiopian Calendar Basics #

Feature Details
Months 13 months: 12 ร— 30 days + Pagume (5 or 6 days)
Leap Year Every 4th year (year % 4 == 3), Pagume has 6 days
Year Offset Ethiopian year is ~7โ€“8 years behind Gregorian
New Year Enkutatash โ€” Meskerem 1 (โ‰ˆ Sept 11/12)
Time System Day starts at 6:00 AM (Ethiopian 12:00 day)

Ethiopian Month Names:

# Amharic English
1 แˆ˜แˆตแŠจแˆจแˆ Meskerem
2 แŒฅแ‰…แˆแ‰ต Tikimt
3 แŠ…แ‹ณแˆญ Hidar
4 แ‰ณแŠ…แˆฃแˆฅ Tahsas
5 แŒฅแˆญ Tir
6 แ‹จแŠซแ‰ฒแ‰ต Yekatit
7 แˆ˜แŒ‹แ‰ขแ‰ต Megabit
8 แˆšแ‹ซแ‹šแ‹ซ Miyazia
9 แŒแŠ•แ‰ฆแ‰ต Ginbot
10 แˆฐแŠ” Sene
11 แˆแˆแˆŒ Hamle
12 แАแˆแˆด Nehase
13 แŒณแŒ‰แˆœ Pagume

๐Ÿงช Testing #

The library ships with 12 test suites covering all modules:

dart test

๐Ÿ“„ License #

MIT License ยฉ Melaku Demeke


๐Ÿ™‹ Contributing #

Pull requests and issues are welcome on GitHub. Please open an issue before submitting large changes.

1
likes
140
points
88
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A comprehensive Ethiopian calendar library for Dart with full support for date conversions, holidays, fasting periods, Bahire Hasab, Geez numerals, and traditional calendar features.

Repository (GitHub)
View/report issues

Topics

#calendar #ethiopian #date #localization

License

MIT (license)

More

Packages that depend on kenat