Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ethiopic calendar #2658

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

feat: ethiopic calendar #2658

wants to merge 8 commits into from

Conversation

gpbl
Copy link
Owner

@gpbl gpbl commented Jan 7, 2025

This PR introduces support for the Ethiopic calendar in the DayPicker.

The PR is still a work in progress. Switch to this branch to start applying changes to the source.

How It Works

The Ethiopic calendar is rendered by importing it from react-day-picker/ethiopic, similar to how we handle the Persian calendar.

import { DayPicker } from 'react-day-picker/ethiopic';

<DayPicker />
  • Understand the correct name, Ethiopian or Ethiopic? "Ethiopic" is correct.

Ethiopic Module

  • ethiopic/index.tsx
    Render DayPicker using the Ethiopic calendar, overriding some props. Complete tests.
  • ethiopic/lib
    Date manipulation and formatting functions compatible with DayPicker's DateLib. Complete tests and fix functions.
  • ethiopic/utils
    Convert dates from/to Gregorian. Complete tests and fix functions.
List of lib functions
  • addDays
  • addMonths
  • addWeeks
  • addYears
  • differenceInCalendarDays
  • differenceInCalendarMonths
  • eachMonthOfInterval
  • endOfBroadcastWeek
  • endOfISOWeek
  • endOfMonth
  • endOfWeek
  • endOfYear
  • format
  • formatNumber
  • getISOWeek
  • getMonth
  • getWeek
  • getYear
  • isAfter
  • isBefore
  • isSameDay
  • isSameMonth
  • isSameYear
  • max
  • min
  • newDate
  • setMonth
  • setYear
  • startOfBroadcastWeek
  • startOfDay
  • startOfISOWeek
  • startOfMonth
  • startOfWeek
  • startOfYear
  • today

Example Component and Docs

  • examples/Ethiopic.tsx: the example components.
  • examples/Ethiopic.test.tsx: test file for the new Ethiopic calendar example.
  • website/docs/docs/localization.mdx: add Ethiopic Calendar paragraph.
  • website/components/playground: add Ethiopic Calendar option.

See Working With the Source Code to start the examples app and reach http://localhost:5173/?example=Ethiopic to see it running.

Numeral System and Locale

  • Understand which locale should be used. Are they included in date-fns already?
  • Understand which numeral systems we need to support.
  • src/types/props.ts, src/types/shared.ts: include the Ethiopic numeral system.
  • Update DateLib to work with the new numeral system (e.g., getDigitMap).

Ethiopic DateLib

Having the Ethiopic date library compatible with the DateLib overrides protocol is the most challenging part of this project. The DateLib is initialized here with the Ethiopic overrides and should work out-of-the-box once we provide the correct functions.

In the absence of a package like date-fns-ethiopic, we can initially include the Ethiopic DateLib override functions in the DayPicker package. Note that not all functions may require an Ethiopic version.

Configuration and Build

  • package.json: includes the Ethiopic calendar module.
  • ethiopic.js: added module export for the Ethiopic calendar.
  • Verify the type export with https://arethetypeswrong.github.io

ethiopic.js Show resolved Hide resolved
@temesgen-mulugeta
Copy link

  • Thinking about the name, I think "Ethiopic" is better. It pays homage to the Geez language, which is the basis of the calendar.

  • When it comes to the numerals. There are specific geez numerals, so I can also work on that and add them to the utility functions, and we can add the support for it.

  • I have implemented most of the date-fns functions that need to be overridden in my repo. But I haven't written tests for it, and I can also assist with that. From my experience, overriding the months and years functions is enough, with the exception of getWeek to get the week count right.
    https://github.com/temesgen-mulugeta/shadcn-ethiopian-date-picker/blob/main/src/lib/EthiopianDateLib.tsx

@gpbl
Copy link
Owner Author

gpbl commented Jan 7, 2025

  • I have implemented most of the date-fns functions that need to be overridden in my repo. But I haven't written tests for it, and I can also assist with that. From my experience, overriding the months and years functions is enough, with the exception of getWeek to get the week count right.

That's wonderful, thanks! Based on your work there, would it be possible to code pure functions that we can unit test, a-la date-fns style?

  • Their names and signatures must match those in http://daypicker.dev/api/classes/DateLib.
  • I expect these functions to populate the /src/ethiopian/lib directory. See, for example, the startOfYear I added as an example in this PR.

From the "List of DateLib functions," which ones do you know for sure we have to add, and which ones can we just ignore?

@gpbl
Copy link
Owner Author

gpbl commented Jan 7, 2025

When it comes to the numerals. There are specific geez numerals, so I can also work on that and add them to the utility functions, and we can add the support for it.

Interesting. Which numerals should we support?

In my implementation, I could rely on Intl native object to switch to other numerals:

private getDigitMap(): Record<string, string> {
const { numerals = "latn" } = this.options;
// Use Intl.NumberFormat to create a formatter with the specified numbering system
const formatter = new Intl.NumberFormat("en-US", {
numberingSystem: numerals
});
// Map Arabic digits (0-9) to the target numerals
const digitMap: Record<string, string> = {};
for (let i = 0; i < 10; i++) {
digitMap[i.toString()] = formatter.format(i);
}
return digitMap;
}

Are all the numerals used in the Ethiopic calendar included in the Intl object? In MacOS, they list two calendars: Ethiopic and Ethiopic (Alete Alem). Is Geʽez another one? 🤔

@temesgen-mulugeta
Copy link

From the "List of DateLib functions," which ones do you know for sure we have to add, and which ones can we just ignore?

From my experience, I’ve identified these as essential practices, and I’ve already implemented them. I will convert them into pure functions and incorporate unit tests for the functions.

  • addMonths
  • addYears
  • differenceInCalendarMonths
  • endOfMonth
  • endOfYear
  • format
  • formatNumber
  • getMonth
  • getWeek
  • getYear
  • isSameMonth
  • isSameYear
  • newDate
  • setYear
  • startOfMonth
  • startOfYear

@temesgen-mulugeta
Copy link

Interesting. Which numerals should we support?

The only numeral we should consider is Geez. The numerals look like '፩', '፪', '፫', '፬'. But I don't think we have support for it on Intl. But the numerals shouldn't be the primary focus. Since most of us use Western Arabic numerals.

@gpbl
Copy link
Owner Author

gpbl commented Jan 12, 2025

I made some progress without knowing much about the Ethiopic calendar.

I scaffolded utilities and functions with the help of Copilot, so they are not guaranteed to work. The next step is to write tests for each of them and then fix the functions to pass the tests.

  • ethiopic/utils to convert dates from/to Gregorian.
  • ethiopic/lib: date manipulation and formatting functions compatible with DayPicker's DateLib.

I wonder work @temesgen-mulugeta's work on MUI (or even the ethiopian date package could be useful here.

Still missing the formatting function. I wonder if we could use the Intl.DateTimeFormat API to format Ethiopic dates?

@temesgen-mulugeta
Copy link

I’ve been quite busy over the past week. I didn’t want to open a PR with an incomplete task, but I’ve now created one to assist you.
I’ve implemented utility functions for converting between Ethiopian and Gregorian dates. I’ve used these functions in over 10 projects, though, to be honest, I originally inherited them from my boss 😁—he’s been using them for over 12 years. However, they are only tested in real-life. I haven't written tests for them.
I’ve also implemented the necessary date manipulation functions in ethiopic/lib, but only the ones that were required. The PR is still incomplete since it needs tests, but it should provide a solid starting point.
Let me know your thoughts! 🚀

@temesgen-mulugeta
Copy link

Still missing the formatting function. I wonder if we could use the Intl.DateTimeFormat API to format Ethiopic dates?

As far as I know Intl doesn't provide date formatting for Ethiopian dates. So what I did was create a date formatting function for the formattings you use on the package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants