Skip to content

Commit

Permalink
Support for Taiwan holidays (#124)
Browse files Browse the repository at this point in the history
* support Taiwan holidays

* Refactor lunarCalendar method to handle parsing errors

* Update variableHolidays to correctly return converted dates

* Refactor variableHolidays to combine array_map and array_filter

* use the Taiwanese language to label the holiday

---------

Co-authored-by: Takeshi Yu <[email protected]>
  • Loading branch information
takeshiyu and Takeshi Yu authored Jan 27, 2024
1 parent 40048aa commit 3b1c0bd
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 2 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
],
"require": {
"php": "^8.1",
"nesbot/carbon": "^2.72.1",
"ext-calendar": "*"
"ext-intl": "*",
"nesbot/carbon": "^2.72.1"
},
"require-dev": {
"laravel/pint": "^1.0",
Expand Down
63 changes: 63 additions & 0 deletions src/Countries/Taiwan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Spatie\Holidays\Countries;

use DateTime;
use DateTimeZone;
use IntlDateFormatter;

class Taiwan extends Country
{
protected string $timezone = 'Asia/Taipei';

public function countryCode(): string
{
return 'tw';
}

protected function allHolidays(int $year): array
{
return array_merge([
'元旦' => '01-01',
'228和平紀念日' => '02-28',
'兒童節' => '04-04',
'雙十國慶' => '10-10',
], $this->variableHolidays($year));
}

/** @return array<string, string> */
protected function variableHolidays(int $year): array
{
return array_filter(array_map(fn ($date) => $this->lunarCalendar($date, $year), [
'農曆春節-正月初一' => '01-01',
'農曆春節-正月初二' => '01-02',
'農曆春節-正月初三' => '01-03',
'端午節' => '05-05',
'中秋節' => '08-15',
]));
}

protected function lunarCalendar(string $input, int $year): ?string
{
$formatter = new IntlDateFormatter(
locale: 'zh-TW@calendar=chinese',
dateType: IntlDateFormatter::SHORT,
timeType: IntlDateFormatter::NONE,
timezone: $this->timezone,
calendar: IntlDateFormatter::TRADITIONAL
);

$lunarDateStr = $year . '-' . $input;
$parsedTimestamp = $formatter->parse($lunarDateStr);

if ($parsedTimestamp === false) {
return null;
}

$dateTime = new DateTime;
$dateTime->setTimestamp($parsedTimestamp);
$dateTime->setTimezone(new DateTimeZone($this->timezone));

return $dateTime->format('m-d');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[
{
"name": "\u5143\u65e6",
"date": "2024-01-01"
},
{
"name": "\u8fb2\u66c6\u6625\u7bc0-\u6b63\u6708\u521d\u4e00",
"date": "2024-02-10"
},
{
"name": "\u8fb2\u66c6\u6625\u7bc0-\u6b63\u6708\u521d\u4e8c",
"date": "2024-02-11"
},
{
"name": "\u8fb2\u66c6\u6625\u7bc0-\u6b63\u6708\u521d\u4e09",
"date": "2024-02-12"
},
{
"name": "228\u548c\u5e73\u7d00\u5ff5\u65e5",
"date": "2024-02-28"
},
{
"name": "\u5152\u7ae5\u7bc0",
"date": "2024-04-04"
},
{
"name": "\u7aef\u5348\u7bc0",
"date": "2024-06-10"
},
{
"name": "\u4e2d\u79cb\u7bc0",
"date": "2024-09-17"
},
{
"name": "\u96d9\u5341\u570b\u6176",
"date": "2024-10-10"
}
]
19 changes: 19 additions & 0 deletions tests/Countries/TaiwanTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Spatie\Holidays\Tests\Countries;

use Carbon\CarbonImmutable;
use Spatie\Holidays\Holidays;

it('can calculate taiwan holidays', function () {
CarbonImmutable::setTestNowAndTimezone('2024-01-01');

$holidays = Holidays::for(country: 'tw')->get();

expect($holidays)
->toBeArray()
->not()->toBeEmpty();

expect(formatDates($holidays))->toMatchSnapshot();

});

0 comments on commit 3b1c0bd

Please sign in to comment.