npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ethiopian-dates

v1.0.2

Published

Ethiopian ↔ Gregorian calendar conversion with Amharic month names, Geez numerals, Ethiopian holidays, date formatting, and day of week. TypeScript, zero dependencies.

Readme

ethiopian-dates

npm version types dependencies

You're building something for Ethiopian users and you need the date to read Sene 4, 2018 instead of June 11, 2026. This package does that conversion in both directions, and handles the parts you'd rather not write yourself: the 13th month, the leap-year rule, Geez numerals, Amharic names, and the full public holiday list including the movable ones.

Zero dependencies. Written in TypeScript, so you get types without installing anything extra.

npm install ethiopian-dates

Convert a date

Pass year, month, day. Months are 1-indexed in both directions, and month 13 is Pagume.

import { toEthiopian, toGregorian } from 'ethiopian-dates';

toEthiopian(2024, 9, 11);
// { year: 2017, month: 1, day: 1, monthName: 'Meskerem', monthNameAmharic: 'መስከረም' }

toGregorian(2017, 1, 1);
// { year: 2024, month: 9, day: 11, monthName: 'September' }

Bad dates throw a RangeError instead of silently converting to something wrong. February 30 won't get past you, and neither will Pagume 6 in a year where Pagume only has 5 days.

Get today

import { todayInEthiopian } from 'ethiopian-dates';

todayInEthiopian();
// { year: 2018, month: 10, day: 4, monthName: 'Sene', monthNameAmharic: 'ሰኔ' }

Uses the local timezone. Pass a Date if you mean a different moment: todayInEthiopian(someDate).

Write Geez numerals

import { toGeez } from 'ethiopian-dates';

toGeez(2017); // '፳፻፲፯'
toGeez(1);    // '፩'
toGeez(100);  // '፻'

Handles the quirks for you: there's no zero, and the coefficient ፩ is dropped before ፻ (100) and ፼ (10,000). Works up to 99,999,999.

Look up holidays

import { getHolidays, isHoliday } from 'ethiopian-dates';

getHolidays(2017);
// All public holidays that year, sorted, each with its Gregorian equivalent:
// [
//   { name: 'Enkutatash', nameAmharic: 'እንቁጣጣሽ', month: 1, day: 1, movable: false,
//     year: 2017, gregorian: { year: 2024, month: 9, day: 11, monthName: 'September' } },
//   ...
// ]

isHoliday(2017, 8, 12);
// { name: 'Fasika (Easter)', nameAmharic: 'ፋሲካ', month: 8, day: 12, movable: true }

isHoliday(2017, 1, 2);
// null

This covers all 12 public holidays, not just the fixed ones:

  • Fixed dates: Enkutatash, Meskel, Genna, Timket, Adwa Victory Day, Workers' Day, Patriots' Victory Day
  • Siklet (Good Friday) and Fasika (Easter), computed with the Orthodox computus that Ethiopia follows
  • Eid al-Fitr, Eid al-Adha (Arafa), and Mawlid from the tabular Hijri calendar

Two things worth knowing before you ship. Islamic holidays carry approximate: true because the observed date follows the moon sighting and can land a day off from the tabular date. And because the lunar year is about 11 days shorter, an Islamic holiday occasionally falls twice in one Ethiopian year; Mawlid did in 2017 EC, and getHolidays returns both occurrences.

Format for your UI

import { formatEthiopian } from 'ethiopian-dates';

formatEthiopian(2017, 1, 1, 'DD MMMM YYYY');
// '01 Meskerem 2017'

formatEthiopian(2017, 1, 1, 'DD MMMM YYYY', 'am');
// '፩ መስከረም ፳፻፲፯'

Tokens: YYYY year, MMMM month name, MM/M month number, DD/D day. The 'am' locale switches to Amharic month names and Geez numerals.

Get the day of the week

import { getDayOfWeek } from 'ethiopian-dates';

getDayOfWeek(2017, 1, 1);
// { name: 'Wednesday', nameAmharic: 'ረቡዕ', index: 2 }

index runs 0 (Monday) through 6 (Sunday).

Constants you can import

| Export | What it is | |---|---| | ETHIOPIAN_MONTHS | All 13 months with English and Amharic names | | ETHIOPIAN_HOLIDAYS | The 7 fixed-date holidays | | WEEK_DAYS | The 7 days with Amharic names | | isEthiopianLeapYear(year) | True when year % 4 === 3 | | ethiopianMonthLength(year, month) | 30, or 5/6 for Pagume |

The calendar, in thirty seconds

Twelve months of exactly 30 days, then Pagume, a 13th month of 5 days (6 in leap years). Leap years come every four years with no century exceptions. The year count runs 7 to 8 behind the Gregorian one because Ethiopia kept an older calculation of the Annunciation. New Year (Enkutatash) falls on September 11, or September 12 right after an Ethiopian leap year.

Under the hood, every conversion goes through Julian Day Numbers, so the two calendars never touch each other directly and the leap-year edge cases fall out of the arithmetic instead of being special-cased.

Working on the package

Using the published package needs nothing special: dist/ is plain ES modules and runs on Node 18+ or any bundler. Developing it is pickier, because the tests run the TypeScript source directly through Node's type stripping:

npm install   # pulls in TypeScript and builds dist/
npm test      # needs Node 23.6+ to run the .ts tests natively
npm run build

The test suite round-trips every single day across 13 years, checks known historical dates, covers the Geez numeral quirks, verifies holiday dates against real observances, and cross-checks a full year of weekdays against JavaScript's Date.

License

MIT