DEV Community

david duymelinck
david duymelinck

Posted on

Yasumi alternative

While I did my deep dive on PHP dates I found the Yasumi library.

I like the library a lot but for me it came with a few to many restrictions.
So instead of improving the library I started my own based on the work the Yasumi already did.

The restrictions that made start my own library

Yasumi is focused on holidays. With holidays most people think of days were they don't need to work.
There are a lot of day in the year that have a meaning for people without the no-work connotation. And that is one of the aspects I wanted in a dates library.

Yasumi also focuses on days while there are also periods that have meaning. I'm thinking of lent for Christians, Ramadam for Muslims. I do think those have a place in a library too.

On the technical side I found it strange you can only select a single provider. What if you want the christmas of multiple countries?

$usa = Yasumi\Yasumi::create('USA', (int) date('Y'));
$canada = Yasumi\Yasumi::create('Canada', (int) date('Y'));

$christmasses = [
   $usa->getHoliday('christmas'),
   $canada->getHoliday('christmas'),
];
Enter fullscreen mode Exit fullscreen mode

It feels excessive to instantiate multiple classes.

While I browsed the code I found that provider relations are hardcoded.
You can't get the Australian capital territory dates without the Australian dates.

So the design of the alternative library already has a few points to explore.

Designing the library

The providers are mostly geographical, so it makes sense to put the dates in a Region.
There are also other providers like ChristianHolidays and CommonHolidays. Christians live on earth so with a bit of bending the definition of a region a religion can be a type of a region.
For common holidays that seems more like a helper class than an actual provider people are going to use. So for my library I will not create it.

A Region should stand alone, and should have the option to call related regions.
A Region day or period should be unique.
A Region should have a method to fetch the dates with a filtering option.

A Day should contain a Region identification, a date and one or more significance types.

A Period is a collection of Day objects with the meta information about the successiveness of the days.
To make it easier to work with the Period there should be first and last item methods.

There should be a class that makes it easier to work with multiple Region object at once.

Status of the library

After four days of thinking and letting AI do the boring parts I have pushed the first commits on the repository.

As you can see the Region implementations are enumns.
An enum made more sense than a class because all Region dates are finite, and an enum is meant to group finite constants.
An enum is not extendable, so that restriction leaves no room for hardcoded relations.
I added an All case to each enum to make it more contextual when using the methods. USA::All->get((int) date('Y')); creates less confusion than USA::IndependenceDay->get((int) date('Y'));

Like Yasumi all regions have the dates in their timezone. For the religious regions the timezone is UTC, because that made the most sense.

I already provided a multiple regions class, but for now that is more a prove of concept than a workable item.

Next steps

The effort of Sacha Telgenhof and the other Yasumi contributers is enormous. And I wanted to have all the dates from Yasumi before I released something there are still parts were the library is still a mess.

One of the things I only decided yesterday is that when a Day has a holiday that is not the day itself, due to falling in an weekend or being pushed later by another holiday, it should be a part of the Day instance instead of being another Day.
The Yasumi library filters those dates by removing the HolidaySubsitute instances. I think that way of working is wastefull because most of the information is the same for the two instances.
So that will require a massive rewrite.

Another decision I made to be fast is to have a NotableTypeCollection as a property of Day, because I wanted the option to have one or more significance bound to a date. For example Christmas is in most western countries a Christian event but also an official holiday. For me one is not less important than than the other.
The Yasumi library has an TYPE_OTHER significance option, and that doesn't sit right by me.
I want the dates to have all their most specified significance.
So that is going to be a research work to get it right as best as possible. I have no doubt I'm going to make mistakes. But that is why I build the library in public.

What I learned from the Yasumi library

Use DateImmutable, I seen too many cloned temporary variables instances to think DateTime is the best way to define a date.

South Korea is the country with the most rules involving dates.

There are a lot of weird rules for holidays.

There are quite a few countries that don't have Saturday and Sunday as their weekend.

It was fun to really get into all that information, and I will continue to expand my knowledge working on my library.

Top comments (0)