kylekatarnls / business-day

Carbon mixin to handle business days
MIT License
306 stars 55 forks source link

Cannot get expression to work properly #84

Open betaSavvy opened 3 years ago

betaSavvy commented 3 years ago

Hi,

I am trying to set a holiday that if it falls on a sunday, the following monday will be a holiday.

return [
    'hari-raya-puasa' => '= 1 shawwal if sunday then next monday', 
]

But got this error

Carbon\Exceptions\InvalidFormatException
DateTime::__construct(): Failed to parse time string (1 shawwal 2020) at position 0 (1): Unexpected character

What is the right way to achieve it?

kylekatarnls commented 3 years ago

Hello,

As of now, alternative calendars (Hijri/Jewish/Lunar) are not compatible with conditional syntax.

I started a fix, you can try it by requiring:

"require": {
  ...
  "cmixin/business-day": "dev-fix/issue-84-support-alt-calendar-with-conditions as 1.14.0"
}

As it involves one more RegExp parsing, it might cost some performance so I still have to find a more optimized way.

betaSavvy commented 3 years ago

@kylekatarnls

Wow that was quick! Just did some test with it and working good so far. Nice work!

Then went on to test another holiday - Hari Raya Haji(aka Eid al-Adha) which falls on the 10th day of the 12th month in the Islamic calendar.

return [
    'hari-raya-haji' => '= 10 dhu al-hijjah if sunday then next monday', 
]

I tried from year 2000-2021, the following years gave me error in test cases.

2004-02-01, 2007-12-27, 2008-12-08, 2009-11-27, 2011-11-06, 2016-09-12, 2019-08-11

I am referencing this source for the particular holiday I am testing Singapore Public Holidays

and this for the hijri/gregorian calendar Islamic/Gregorian Calendar

Any idea why this happens?

kylekatarnls commented 3 years ago

Can you please add '= 10 dhu al-hijjah' in your config and check: Carbon::getYearHolidays() for each year and for each day what day of week it is, so I can see if either 10 dhu al-hijjah (based on Hijri calendar) is the mismatch or if the if-then rule fails. Thanks 🙏

betaSavvy commented 3 years ago
Hari Raya Haji: 16/03/2000 Thursday
Hari Raya Haji: 06/03/2001 Tuesday
Hari Raya Haji: 23/02/2002 Saturday
Hari Raya Haji: 12/02/2003 Wednesday
Hari Raya Haji: 02/02/2004 Monday         // this should be observed, actual is 01/02/2004 Sunday
Hari Raya Haji: 21/01/2005 Friday
Hari Raya Haji: 10/01/2006 Tuesday
Unknown: 31/12/2006 Sunday                // No idea about this, the id is hari-raya-haji-oc-2
Hari Raya Haji: 20/12/2007 Thursday       // actual should be is 27/12/2007 Thursday
Hari Raya Haji: 09/12/2008 Tuesday        // actual should be is 08/12/2008 Monday
Hari Raya Haji: 28/11/2009 Saturday       // actual should be is 27/11/2008 Friday
Hari Raya Haji: 17/11/2010 Wednesday
Hari Raya Haji: 07/11/2011 Monday         // this should be observed, actual is 06/11/2011 Thursday
Hari Raya Haji: 26/10/2012 Friday
Hari Raya Haji: 15/10/2013 Tuesday
Hari Raya Haji: 05/10/2014 Sunday
Hari Raya Haji (observed): 06/10/2014 Monday
Hari Raya Haji: 24/09/2015 Thursday
Hari Raya Haji: 13/09/2016 Tuesday        // actual should be is 12/09/2016 Monday
Hari Raya Haji: 02/09/2017 Saturday
Hari Raya Haji: 22/08/2018 Wednesday
Hari Raya Haji: 12/08/2019 Monday         // this should be observed, actual is 11/08/2019 Thursday
Hari Raya Haji: 31/07/2020 Friday
Hari Raya Haji: 20/07/2021 Tuesday

The above data(2000 - 2021) is based on the following config:

return [
    'hari-raya-haji' => '= 10 dhu al-hijjah',
    'hari-raya-haji-observed' => '= 10 dhu al-hijjah if sunday then next monday',
];

Year 2014 works correctly with both holiday and observed holiday.