kylekatarnls / business-day

Carbon mixin to handle business days
MIT License
307 stars 56 forks source link

How to add multiple independence-day configuration items in carbon.php? #58

Closed liuyong888 closed 3 years ago

liuyong888 commented 3 years ago

hi,

I have the following two questions

  1. Some weekends are also weekdays,so I need add multiple independence-day.
  2. I found that the number of days off on some festivals is wrong in our country. For example: China’s National Day holiday generally has seven days holiday, but I tested it only has three days holiday. How can I modify or reset it in the carbon.php file.
kylekatarnls commented 3 years ago

Hello.

I don't see the relation between weekends, weekdays and independence-day, please show code with the input/output you expect and what you actually get.

Custom holidays can be defined as the third argument of enable(), see $additionalHolidays in the first example of the documentation: https://github.com/kylekatarnls/business-day#usage

For error in the base list, please edit this file to propose a pull-request: https://github.com/kylekatarnls/business-day/blob/master/src/Cmixin/Holidays/cn-national.php

Thanks,

liuyong888 commented 3 years ago

Hi,

First of all thank you very much for your reply.

Development environment: Laravel Framework 7.29.2

  1. 2021-02-20 is Saturday, but it is a working day in China, and there are still some cases of working on Saturday or Sunday. So how do I set up multiple independence-days? image

  2. 10-01 is the National Day of China. China National Day holiday is generally seven days off from 10-01 to 10-07. But I only see in the code that isBusinessDay() is false for the three days from 10-01 to 10-03, and isBusinessDay() is true from 10-04 to 10-07. I hope that isBusinessDay() from 10-01 to 10-07 should be Is false. image

Thanks,

kylekatarnls commented 3 years ago

1. "Independence Days" are working days? 👀

You can customize the check that is run for isBusinessDay(): In this example: https://github.com/kylekatarnls/business-day#setbusinessdaychecker 2020-12-06 is a working day despite it's Sunday.

Is it something official that should always apply for any business with country set to China?

2. "generally"? Can you confirm it's officially 7 days and apply for most businesses, schools, post offices etc.? As it's open-source you can edit https://github.com/kylekatarnls/business-day/blob/master/src/Cmixin/Holidays/cn-national.php to add missing days. Please provide a link to some official government website alongside the pull-request if so and I'll merge your change. Thanks. 🙏

liuyong888 commented 3 years ago
  1. Yes, I mean to set the working day But I still have a question, do I have to manually call the setBusinessDayChecker() method once? How to write many custom business days into the config/carbon.php file? If my idea is wrong please tell me the right way. image

  2. I don’t know how to modify it. I have seen that 10-01 is set as National Day in the cn-national.php file, but why there are only three days off instead of seven days off? I don’t know how it is achieved. My needs It is the National Day from 10-01 to 10-07, which are all days off. This is the official announcement of our country(China Mainland) : http://www.gov.cn/fuwu/2020-11/25/content_5564533.htm No English version.

    Tips: The annual holiday announcements are a little bit different, so this requires manual modification of the configuration regularly.

Thanks.

kylekatarnls commented 3 years ago

1. For now, it's not something doable in the static config, so it should be:

Carbon::setBusinessDayChecker(function (CarbonInterface $date) {
    return $date->isWeekday()
        && !$date->isHoliday()
        || in_array($date->format('Y-m-d'), [
            '2021-02-07',
            '2021-02-20',
            '2021-04-25',
            '2021-05-08',
        ]);
});

added in a global place. If you use Laravel, the boot() method of your AppServiceProvider is a good place.

=> null is to cancel (by ID, not by date) an holiday from the selected region.

2. I will add them.

liuyong888 commented 3 years ago

I got it, thanks.

kylekatarnls commented 3 years ago

If you want to take a look, here is the planned update for the list of China including the golden week: https://github.com/kylekatarnls/business-day/pull/59/files#diff-695c9dad5f1c50f74d40ca0fb2cb02684104a1b58734f13fd67a1744704ce81b

I also investigated a bit deeper in compensation work days. And I'm not sure there are much we can do as I can't find a way to determine them in advance in a predictible (for instance know the compensation work days of 2022, 2023, etc.)

If you know how dates are calculated, it can help, else, each application will need to maintain its own list or use a updated API to get them. (By the way, we'll probably have our own API URL endpoint at some point to provide more metadata and avoid the library to be to heavy.)

liuyong888 commented 3 years ago

First of all, let me explain that except for some regular holidays (eg: National Day .etc) dates are fixed.

The Chinese lunar calendar is very complicated (eg: Spring Festival, Mid-Autumn Festival .etc, the holiday dates of the Gregorian calendar are different each year), and it may take an expert who understands the Chinese lunar calendar to figure it out.

If it only relies on a set of algorithms, it will be very complicated, and secondly, the specific government announcement shall prevail.

So currently I use the third-party api interface to get all holidays and working days to configure my carbon.php configuration file or I manually modify the custom configuration file regularly.

I think an API interface is probably the best way to keep the data accurate.

kylekatarnls commented 3 years ago

Chinese lunar calendar is not a problem. We have a LunarCalendar to convert lunar-month/lunar-day date into the first date that matches in the Gregorian current year. https://github.com/kylekatarnls/business-day/blob/master/src/Cmixin/BusinessDay/Calendar/LunarCalendar.php

Based on: https://github.com/isee15/Lunar-Solar-Calendar-Converter https://github.com/peterkahl/chinese-lunar-calendar

So except for Gregorian year that contains twice a given Lunar calendar year, we'll properly display those dates like we do currently for the Lunar new year and Spring festival:

'spring-festival' => '= chinese 01-01 - 1 day',
'chinese-01-0-01' => '= chinese 01-01',
'chinese-05-0-05' => '= chinese 05-05',
'chinese-08-0-15' => '= chinese 08-15',

So if compensation work days are based on Chinese lunar calendar, we can handle it, for instance if (unless government exception) the closest week-end day before Lunar new year is typically worked, we can calculate the Gregorian date easily.

liuyong888 commented 3 years ago

Oh, I see it. I'll keep an eye on it.

liuyong888 commented 3 years ago

I hope merge Handle China National Day #59 into master from fix/issue-58-china-holidays as soon as possible. @kylekatarnls

kylekatarnls commented 3 years ago

No need to put pressure on it.

As seen above, you can work around those errors from application side, using:

'with' => [
    '03-08-12:00' => null,
    'national-day-golden-week-1' => '= 10-02 if year >= 2000',
    'national-day-golden-week-2' => '= 10-03 if year >= 2000',
    'national-day-golden-week-3' => '= 10-04 if year >= 2000',
    'national-day-golden-week-4' => '= 10-05 if year >= 2000',
    'national-day-golden-week-5' => '= 10-06 if year >= 2000',
    'national-day-golden-week-6' => '= 10-07 if year >= 2000',
]

Using null to remove days (by their IDs) that should not be holidays (no effect on week-end). And "id" => "= expression", pairs to add dynamic holidays (Year can be added to be applied only for given year).

Last, using Carbon::setBusinessDayChecker(), you can enforce compensation working days on week-end days.

So rather than merging by chunks in a hurry. I will try to get a working long-term solution (meaning able to support compensation natively by config instead of setBusinessDayChecker) and try to make it reliable for next years as per probable dates.

liuyong888 commented 3 years ago

OK, I'm looking forward to it.