Skip to content

Commit

Permalink
Merge pull request #104 from heiglandreas/addArgentine
Browse files Browse the repository at this point in the history
  • Loading branch information
heiglandreas committed Oct 14, 2022
2 parents 4608f6b + 673ded4 commit fdf02ea
Show file tree
Hide file tree
Showing 11 changed files with 290 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/actions.yml
Expand Up @@ -103,7 +103,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
php-version: "8.0"
coverage: xdebug
- name: Install
run: composer update
Expand Down
11 changes: 11 additions & 0 deletions share/AR-armenian.xml
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<holidays xmlns="https://heigl.org/holidays"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="holidays.xsd https://heigl.org/xml/xsd/holidays.xsd"
xmlns:xi="http://www.w3.org/2001/XInclude"
>
<xi:include href="AR.xml" parse="xml" xpointer="xpointer(*/*)">
<xi:fallback></xi:fallback>
</xi:include>
<date day="24" month="4" free="true" comment="Day of Action for Tolerance and Respect among Peoples">Día de Acción por la Tolerancia y el Respeto entre los Pueblos</date>
</holidays>
11 changes: 11 additions & 0 deletions share/AR-catholic.xml
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<holidays xmlns="https://heigl.org/holidays"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="holidays.xsd https://heigl.org/xml/xsd/holidays.xsd"
xmlns:xi="http://www.w3.org/2001/XInclude"
>
<xi:include href="AR.xml" parse="xml" xpointer="xpointer(*/*)">
<xi:fallback></xi:fallback>
</xi:include>
<easter offset="-3" free="true" comment="Holy Thursday">Jueves Santo</easter>
</holidays>
13 changes: 13 additions & 0 deletions share/AR-islam.xml
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<holidays xmlns="https://heigl.org/holidays"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="holidays.xsd https://heigl.org/xml/xsd/holidays.xsd"
xmlns:xi="http://www.w3.org/2001/XInclude"
><!--
<xi:include href="AR.xml" parse="xml" xpointer="xpointer(*/*)">
<xi:fallback></xi:fallback>
</xi:include>-->
<date day="1" month="10" calendar="islamic-umalqura" free="true" comment="Festival of Breaking of the Fast of the Holy Month of Ramadan">Fiesta de la Ruptura del Ayuno del Sagrado Mes de Ramadán</date>
<date day="10" month="12" free="true" calendar="islamic-umalqura" comment="Festival of Sacrifice">Fiesta del Sacrificio</date>
<date day="1" month="1" free="true" calendar="islamic-umalqura" comment="Islamic New Year">Año Nuevo Islámico</date>
</holidays>
17 changes: 17 additions & 0 deletions share/AR-judaism.xml
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<holidays xmlns="https://heigl.org/holidays"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="holidays.xsd https://heigl.org/xml/xsd/holidays.xsd"
xmlns:xi="http://www.w3.org/2001/XInclude"
>
<date day="15" month="8" free="true" calendar="hebrew" comment="Passover">Pésaj</date>
<date day="16" month="8" free="true" calendar="hebrew" comment="Passover">Pésaj</date>
<date day="21" month="8" free="true" calendar="hebrew" comment="Passover">Pésaj</date>
<date day="22" month="8" free="true" calendar="hebrew" comment="Passover">Pésaj</date>
<date day="1" month="1" free="true" calendar="hebrew" comment="Jewish New Year">Año Nuevo Judío</date>
<date day="2" month="1" free="true" calendar="hebrew" comment="Jewish New Year">Año Nuevo Judío</date>
<date day="10" month="1" free="true" calendar="hebrew" comment="Day of Atonement">Día del Perdón </date>
<xi:include href="AR.xml" parse="xml" xpointer="xpointer(*/*)">
<xi:fallback></xi:fallback>
</xi:include>
</holidays>
35 changes: 35 additions & 0 deletions share/AR.xml
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<holidays xmlns="https://heigl.org/holidays"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="holidays.xsd https://heigl.org/xml/xsd/holidays.xsd"
>
<resources>
<resource href="https://en.wikipedia.org/wiki/Public_holidays_in_Argentina" lastChecked="2022-10-13">Wikipedia</resource>
</resources>
<date day="1" month="1" free="true" comment="New Year's Day">Año Nuevo</date>
<easter offset="-48" free="true" comment="Carnival">Carnaval</easter>
<easter offset="-47" free="true" comment="Carnival">Carnaval</easter>
<date day="24" month="3" free="true" comment="Day of rememberance for truth and justice">Día Nacional de la Memoria por la Verdad y la Justicia</date>
<date day="2" month="4" free="true" comment="Day of the veterans and fallen of the falklands war">Día del Veterano y de los Caídos en la Guerra de Malvinas</date>
<easter offset="-2" free="true" comment="Good Friday">Viernes Santo</easter>
<date day="1" month="5" free="true" comment="Labour Day">Día del Trabajador</date>
<date day="25" month="5" forwardto="monday" forwardwhen="thursday friday saturday sunday" free="true" rewindto="monday" rewindwhen="tuesday wednesday" comment="May Revolution">
Día de la Revolución de Mayo
</date>
<date day="17" forwardto="monday" free="true" month="6" forwardwhen="thursday friday saturday sunday" rewindto="monday" rewindwhen="tuesday wednesday" comment="Anniversary of the Passing of General Martín Miguel de Güemes">
Paso a la Inmortalidad del General Martín Miguel de Güemes
</date>
<date day="20" month="6" free="true" comment="General Manuel Belgrano Memorial Day">Paso a la Inmortalidad del General Manuel Belgrano</date>
<date day="9" month="7" free="true" comment="Independence Day">Día de la Independencia</date>
<date day="17" forwardto="monday" free="true" month="8" forwardwhen="thursday friday saturday sunday" rewindto="monday" rewindwhen="tuesday wednesday" comment="General José de San Martín Memorial Day">
Paso a la Inmortalidad del General José de San Martín
</date>
<date day="12" forwardto="monday" free="true" month="10" forwardwhen="thursday friday saturday sunday" rewindto="monday" rewindwhen="tuesday wednesday" comment="Day of Respect for Cultural Diversity">
Día del Respeto a la Diversidad Cultural
</date>
<date day="20" forwardto="monday" free="true" month="11" forwardwhen="thursday friday saturday sunday" rewindto="monday" rewindwhen="tuesday wednesday" comment="National Sovereignty Day">
Día de la Soberanía Nacional
</date>
<date day="8" month="12" free="true" comment="Immaculate Conception Day">Día de la Inmaculada Concepción de María</date>
<date day="25" month="12" free="true" comment="Christmas">Navidad</date>
</holidays>
12 changes: 12 additions & 0 deletions share/holidays.xsd
Expand Up @@ -68,6 +68,8 @@
<xs:attribute name="free" type="xs:boolean" use="required"/>
<xs:attribute name="comment" type="xs:string"/>
<xs:attribute name="calendar" type="calendars"/>
<xs:attribute name="previous" type="daynames" use="optional"/>
<xs:attribute name="previouswhen" type="daynamelist" use="optional"/>
</xs:attributeGroup>
<xs:attributeGroup name="relativeAttributes">
<xs:attribute name="day" type="dayInt" use="required"/>
Expand All @@ -80,6 +82,14 @@
<xs:attribute name="href" type="xs:anyURI" use="required"/>
<xs:attribute name="lastChecked" type="xs:date" use="required" />
</xs:attributeGroup>
<xs:attributeGroup name="forward">
<xs:attribute name="forwardto" type="daynames" use="optional"/>
<xs:attribute name="forwardwhen" type="daynamelist" use="optional" />
</xs:attributeGroup>
<xs:attributeGroup name="rewind">
<xs:attribute name="rewindto" type="daynames" use="optional"/>
<xs:attribute name="rewindwhen" type="daynamelist" use="optional" />
</xs:attributeGroup>
<xs:element name="resources">

</xs:element>
Expand Down Expand Up @@ -153,6 +163,8 @@
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attributeGroup ref="dateAttributes"/>
<xs:attributeGroup ref="rewind"/>
<xs:attributeGroup ref="forward"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
Expand Down
52 changes: 40 additions & 12 deletions src/CalendarDay.php
Expand Up @@ -80,9 +80,25 @@ public function setGregorianYear(int $year): void
$this->calendar->add(IntlCalendar::FIELD_YEAR, $diff);
}

public static function setGregorianYearForDate(int $year, IntlCalendar $calendar): IntlCalendar
{
$datetime = $calendar->toDateTime();
$yearDiff = $year - (int) $datetime->format('Y');

$calendar->set(IntlCalendar::FIELD_YEAR, $calendar->get(IntlCalendar::FIELD_YEAR) + $yearDiff);
if ($calendar->toDateTime()->format('Y') < $year) {
$calendar->set(IntlCalendar::FIELD_YEAR, $calendar->get(IntlCalendar::FIELD_YEAR) + 1);
}
if ($calendar->toDateTime()->format('Y') > $year) {
$calendar->set(IntlCalendar::FIELD_YEAR, $calendar->get(IntlCalendar::FIELD_YEAR) - 1);
}

return $calendar;
}

public function isSameDay(DateTimeInterface $dateTime): bool
{
$cal = clone $this->calendar;
$cal = clone $this->calendar;
$cal->setTime($dateTime->getTimestamp() * 1000);

if (null !== $this->year &&
Expand All @@ -101,7 +117,7 @@ public function isSameDay(DateTimeInterface $dateTime): bool
public function isFollowUpDay(DateTimeInterface $dateTime, string $followUpDay): bool
{
$cal = clone $this->calendar;
$cal->set(IntlCalendar::FIELD_YEAR, (int) $dateTime->format('Y'));
$cal = self::setGregorianYearForDate((int) $dateTime->format('Y'), $cal);
$day = $cal->toDateTime();
$day->modify('next ' . $followUpDay);
$cal->setTime($day->getTimestamp() * 1000);
Expand All @@ -119,6 +135,27 @@ public function isFollowUpDay(DateTimeInterface $dateTime, string $followUpDay):
return $cal->get(IntlCalendar::FIELD_DAY_OF_MONTH) === $cal2->get(IntlCalendar::FIELD_DAY_OF_MONTH);
}

public function isPreviousDay(DateTimeInterface $dateTime, string $previousDay): bool
{
$cal = clone $this->calendar;
$cal = self::setGregorianYearForDate((int) $dateTime->format('Y'), $cal);
$day = $cal->toDateTime();
$day->modify('previous ' . $previousDay);
$cal->setTime($day->getTimestamp() * 1000);
$cal2 = clone $this->calendar;
$cal2->setTime($dateTime->getTimestamp() * 1000);

if (null !== $this->year && $cal->get(IntlCalendar::FIELD_YEAR) !== $cal2->get(IntlCalendar::FIELD_YEAR)) {
return false;
}

if ($cal->get(IntlCalendar::FIELD_MONTH) !== $cal2->get(IntlCalendar::FIELD_MONTH)) {
return false;
}

return $cal->get(IntlCalendar::FIELD_DAY_OF_MONTH) === $cal2->get(IntlCalendar::FIELD_DAY_OF_MONTH);
}

public function getWeekdayForGregorianYear(int $year): int
{
$cal = $this->getDayForGregorianYear($year);
Expand All @@ -132,16 +169,7 @@ private function getDayForGregorianYear(int $gregorianYear): IntlCalendar
$cal->set(IntlCalendar::FIELD_MONTH, $this->month - 1);
$cal->set(IntlCalendar::FIELD_DAY_OF_MONTH, $this->day);

$datetime = $cal->toDateTime();
$yearDiff = $gregorianYear - (int) $datetime->format('Y');

$cal->set(IntlCalendar::FIELD_YEAR, $cal->get(IntlCalendar::FIELD_YEAR) + $yearDiff);
if ($cal->toDateTime()->format('Y') < $gregorianYear) {
$cal->set(IntlCalendar::FIELD_YEAR, $cal->get(IntlCalendar::FIELD_YEAR) + 1);
}
if ($cal->toDateTime()->format('Y') > $gregorianYear) {
$cal->set(IntlCalendar::FIELD_YEAR, $cal->get(IntlCalendar::FIELD_YEAR) - 1);
}
$cal = self::setGregorianYearForDate($gregorianYear, $cal);

return $cal;
}
Expand Down
6 changes: 5 additions & 1 deletion src/HolidayIteratorFactory.php
Expand Up @@ -131,7 +131,11 @@ private function getElement(DOMElement $child): HolidayIteratorItemInterface
return new Date(
$child->textContent,
$this->getFree($child),
$day
$day,
$child->hasAttribute('forwardto')?$child->getAttribute('forwardto'):'',
$child->hasAttribute('forwardwhen')?explode(' ', $child->getAttribute('forwardwhen')):[],
$child->hasAttribute('rewindto')?$child->getAttribute('rewindto'):'',
$child->hasAttribute('rewindwhen')?explode(' ', $child->getAttribute('rewindwhen')):[],
);
case 'dateFollowUp':
$day = CalendarDayFactory::createCalendarDay(
Expand Down
58 changes: 57 additions & 1 deletion src/IteratorItem/Date.php
Expand Up @@ -32,27 +32,63 @@

namespace Org_Heigl\Holidaychecker\IteratorItem;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use IntlCalendar;
use Org_Heigl\Holidaychecker\CalendarDay;
use Org_Heigl\Holidaychecker\HolidayIteratorItemInterface;
use function array_map;
use function in_array;

class Date implements HolidayIteratorItemInterface
{
/** @var CalendarDay */
private $calendarDay;

/** @var bool */
private $holiday;

/** @var string */
private $name;

public function __construct(string $name, bool $holiday, CalendarDay $day)
/** @var string */
private $forwardTo;

/** @var array */
private $forwardWhen;

/** @var string */
private $rewindTo;

/** @var array */
private $rewindWhen;

public function __construct(string $name, bool $holiday, CalendarDay $day, string $forwardTo = '', array $forwardWhen = [], string $rewindTo = '', array $rewindWhen = [])
{
$this->calendarDay = $day;
$this->holiday = $holiday;
$this->name = $name;
$this->forwardTo = $forwardTo;
$this->forwardWhen = self::replacedDays($forwardWhen);
$this->rewindTo = $rewindTo;
$this->rewindWhen = self::replacedDays($rewindWhen);
}

public function dateMatches(DateTimeInterface $date): bool
{
$weekday = $this->calendarDay->getWeekdayForGregorianYear((int) $date->format('Y'));
if (in_array($weekday, $this->forwardWhen, true)) {
return $this->calendarDay->isFollowUpDay($date, $this->forwardTo);
}

if (in_array($weekday, $this->rewindWhen, true)) {
return $this->calendarDay->isPreviousDay($date, $this->rewindTo);
}

if ($date instanceof DateTime) {
$date = DateTimeImmutable::createFromMutable($date);
}
return $this->calendarDay->isSameDay($date);
}

Expand All @@ -65,4 +101,24 @@ public function isHoliday(): bool
{
return $this->holiday;
}

private static function replacedDays(array $replaced): array
{
$daymap = [
'sunday' => IntlCalendar::DOW_SUNDAY,
'monday' => IntlCalendar::DOW_MONDAY,
'tuesday' => IntlCalendar::DOW_TUESDAY,
'wednesday' => IntlCalendar::DOW_WEDNESDAY,
'thursday' => IntlCalendar::DOW_THURSDAY,
'friday' => IntlCalendar::DOW_FRIDAY,
'saturday' => IntlCalendar::DOW_SATURDAY,
];

return array_map(function (string $day) use ($daymap) {
if (! isset($daymap[$day])) {
return null;
}
return $daymap[$day];
}, $replaced);
}
}

0 comments on commit fdf02ea

Please sign in to comment.