Skip to content

Commit

Permalink
Implement getHolidayName (#14)
Browse files Browse the repository at this point in the history
* Implement getHolidayName
* Allow to call with DateTime objects
* Implement swapDateTimeParam and isDateTimeInstance methods
  • Loading branch information
kylekatarnls authored Nov 5, 2018
1 parent ad74d83 commit c12276f
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 22 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"description": "Carbon mixin to handle business days",
"type": "library",
"require": {
"nesbot/carbon": "^1.26.2 || ^2.0"
"nesbot/carbon": "^1.26.2 || ^2.0",
"ext-calendar": "*"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.0"
Expand Down
29 changes: 29 additions & 0 deletions prepare-names-files.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

$keys = array();
foreach (glob('src/Cmixin/Holidays/*.php') as $file) {
$keys = array_merge($keys, include $file);
}
$keys = array_keys($keys);
$length = max(array_map('strlen', $keys));
sort($keys);

foreach (glob('src/Cmixin/HolidayNames/*.php') as $file) {
$data = include $file;
$newData = array();

foreach ($keys as $key) {
$newData[$key] = isset($data[$key]) ? $data[$key] : 'Unknown';
}

if (true || $newData !== $data) {
$data = str_replace('array (', 'array(', var_export($newData, true));
$data = preg_replace_callback('/^\s*\'([^\']+)\'\s*=>/m', function ($match) use ($length) {
$key = $match[1];
$spaces = str_repeat(' ', $length - strlen($key));

return " '$key'$spaces =>";
}, $data);
file_put_contents($file, "<?php\n\nreturn $data;\n");
}
}
9 changes: 3 additions & 6 deletions src/Cmixin/BusinessDay.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,10 @@ public function currentOrPreviousBusinessDay()
public function addBusinessDays($factor = 1)
{
$getThisOrToday = static::getThisOrToday();
$carbonClass = static::getCarbonClass();
$swap = static::swapDateTimeParam();

return function ($days = 1, $self = null) use ($factor, $getThisOrToday, $carbonClass) {
if ($days instanceof \DateTime || $days instanceof \DateTimeInterface) {
$self = $carbonClass::instance($days);
$days = 1;
}
return function ($days = 1, $self = null) use ($factor, $getThisOrToday, $swap) {
$swap($days, $self, 1);

/** @var Carbon|BusinessDay $self */
$self = $getThisOrToday($self, isset($this) ? $this : null);
Expand Down
65 changes: 65 additions & 0 deletions src/Cmixin/BusinessDay/Holiday.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

class Holiday extends HolidaysList
{
const DEFAULT_HOLIDAY_LOCALE = 'en';

public $holidayNames = array();

/**
* Get the identifier of the current holiday or false if it's not a holiday.
*
Expand Down Expand Up @@ -53,4 +57,65 @@ public function isHoliday()
return $self->getHolidayId() !== false;
};
}

/**
* Get the holidays in the given language.
*
* @return \Closure
*/
public function getHolidayNamesDictionary()
{
$mixin = $this;
$defaultLocale = static::DEFAULT_HOLIDAY_LOCALE;

return function ($locale) use ($mixin, $defaultLocale) {
if (isset($mixin->holidayNames[$locale])) {
return $mixin->holidayNames[$locale] ?: $mixin->holidayNames[$defaultLocale];
}

$file = __DIR__."/../HolidayNames/$locale.php";
if (!file_exists($file)) {
$mixin->holidayNames[$locale] = false;
$locale = $defaultLocale;
$file = __DIR__."/../HolidayNames/$locale.php";
}

return $mixin->holidayNames[$locale] = include $file;
};
}

/**
* Get the name of the current holiday (using the locale given in parameter or the current date locale)
* or false if it's not a holiday.
*
* @return \Closure
*/
public function getHolidayName()
{
$carbonClass = static::getCarbonClass();
$getThisOrToday = static::getThisOrToday();
$swap = static::swapDateTimeParam();
$dictionary = $this->getHolidayNamesDictionary();

return function ($locale = null, $self = null) use ($carbonClass, $getThisOrToday, $swap, $dictionary) {
$swap($locale, $self);

/** @var Carbon|BusinessDay $self */
$self = $getThisOrToday($self, isset($this) ? $this : null);
$key = $self->getHolidayId();

if ($key === false) {
return false;
}

if (!$locale) {
$locale = (isset($self->locale) ? $self->locale : $carbonClass::getLocale()) ?: 'en';
}

/* @var string $key */
$names = $dictionary(preg_replace('/^([^_-]+)([_-].*)$/', '$1', $locale));

return isset($names[$key]) ? $names[$key] : 'Unknown';
};
}
}
9 changes: 3 additions & 6 deletions src/Cmixin/BusinessDay/HolidayObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,10 @@ public function isObservedHoliday()
{
$mixin = $this;
$getThisOrToday = static::getThisOrToday();
$carbonClass = static::getCarbonClass();
$swap = static::swapDateTimeParam();

return function ($name = null, $self = null) use ($mixin, $getThisOrToday, $carbonClass) {
if ($name instanceof \DateTime || $name instanceof \DateTimeInterface) {
$self = $carbonClass::instance($name);
$name = null;
}
return function ($name = null, $self = null) use ($mixin, $getThisOrToday, $swap) {
$swap($name, $self);

if (!$name) {
/** @var Carbon|BusinessDay $self */
Expand Down
20 changes: 20 additions & 0 deletions src/Cmixin/BusinessDay/MixinBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,24 @@ public function getThisOrToday()
return $self ?: $staticClass::today();
};
}

public function isDateTimeInstance()
{
return function ($value) {
return $value instanceof \DateTime || $value instanceof \DateTimeInterface;
};
}

public function swapDateTimeParam()
{
$check = static::isDateTimeInstance();
$staticClass = static::getCarbonClass();

return function (&$date, &$target, $defaultValue = null) use ($check, $staticClass) {
if ($check($date)) {
$target = $staticClass::instance($date);
$date = $defaultValue;
}
};
}
}
32 changes: 32 additions & 0 deletions src/Cmixin/HolidayNames/en.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

return array(
'armistice-1918' => 'Armistice 1918',
'ascension' => 'Ascension',
'assumption' => 'Assomption',
'christmas' => 'Christmas',
'christmas-next-day' => 'Christmas next day',
'easter' => 'Easter',
'easter-monday' => 'Easter Monday',
'epiphany' => 'Epiphany',
'good-friday' => 'Good Friday',
'independence-day' => 'Independence Day',
'labor-day' => 'Labor Day',
'liberation-day' => 'Liberation Day',
'memorial-day' => 'Memorial Day',
'mlk-day' => 'Martin Luther King Jr. Day',
'national-day' => 'National Day',
'new-year' => 'New Year',
'new-year-next-day' => 'New Year next day',
'pentecost' => 'Pentecost',
'pentecost-monday' => 'Pentecost Monday',
'preseren-day' => 'Prešeren Day',
'rebellion-day' => 'Rebellion Day',
'reformation-day' => 'Reformation Day',
'royal-day' => 'Royal Day',
'thanksgiving' => 'Thanksgiving',
'toussaint' => 'Toussaint',
'vacation-day' => 'Vacation Day',
'vacation-next-day' => 'Vacation Day next day',
'victory-1945' => 'Victory 1945',
);
32 changes: 32 additions & 0 deletions src/Cmixin/HolidayNames/fr.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

return array(
'armistice-1918' => 'Armistice 1918',
'ascension' => 'Ascension',
'assumption' => 'Assomption',
'christmas' => 'Noël',
'christmas-next-day' => 'Saint Etienne',
'easter' => 'Pâques',
'easter-monday' => 'Lundi de Pâques',
'epiphany' => 'Épiphanie',
'good-friday' => 'Vendredi Saint',
'independence-day' => 'Indépendance',
'labor-day' => 'Fête du travail',
'liberation-day' => 'Libération',
'memorial-day' => 'Jour commémoratif',
'mlk-day' => 'Jour de Martin Luther King',
'national-day' => 'Fête nationale',
'new-year' => 'Nouvel an',
'new-year-next-day' => 'Lendemain du nouvel an',
'pentecost' => 'Pentecôte',
'pentecost-monday' => 'Lundi de Pentecôte',
'preseren-day' => 'Jour de Prešeren',
'rebellion-day' => 'Jour de la Rébellion',
'reformation-day' => 'Jour de la Reformation',
'royal-day' => 'Jour royal',
'thanksgiving' => 'Thanksgiving',
'toussaint' => 'Toussaint',
'vacation-day' => 'Jour de vacances',
'vacation-next-day' => 'Lendemain du jour de vacances',
'victory-1945' => 'Victoire 1945',
);
32 changes: 32 additions & 0 deletions src/Cmixin/HolidayNames/nl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

return array(
'armistice-1918' => 'Wapenstilstand 1918',
'ascension' => 'Hemelvaart',
'assumption' => 'Veronderstelling',
'christmas' => 'Eerste Kerstdag',
'christmas-next-day' => 'Tweede Kerstdag',
'easter' => 'Paaszondag',
'easter-monday' => 'Paasmaandag',
'epiphany' => 'Driekoningen',
'good-friday' => 'Goede Vrijdag',
'independence-day' => 'Onafhankelijkheidsdag',
'labor-day' => 'Dag van de Arbeid',
'liberation-day' => 'Bevrijdingsdag',
'memorial-day' => 'Herdenkingsdag',
'mlk-day' => 'Martin Luther King Jr. Day',
'national-day' => 'Nationale Dag',
'new-year' => 'Nieuwjaarsdag',
'new-year-next-day' => 'Nieuw jaar de volgende dag',
'pentecost' => 'Pinksterzondag',
'pentecost-monday' => 'Pinkstermaandag',
'preseren-day' => 'Prešeren Dag',
'rebellion-day' => 'Rebelliedag',
'reformation-day' => 'Reformatie Dag',
'royal-day' => 'Koningsdag',
'thanksgiving' => 'Dankzegging',
'toussaint' => 'Toussaint',
'vacation-day' => 'Vakantiedag',
'vacation-next-day' => 'Vakantiedag volgende dag',
'victory-1945' => 'Overwinning 1945',
);
32 changes: 32 additions & 0 deletions src/Cmixin/HolidayNames/sl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

return array(
'armistice-1918' => 'Premirje 1918',
'ascension' => 'Vzpon',
'assumption' => 'Marijino vnebovzetje',
'christmas' => 'Božič',
'christmas-next-day' => 'Božič naslednji dan',
'easter' => 'Velika noč',
'easter-monday' => 'Velikonočni ponedeljek',
'epiphany' => 'Razodetje',
'good-friday' => 'Dober petek',
'independence-day' => 'Dan samostojnosti in enotnosti',
'labor-day' => 'Dan dela',
'liberation-day' => 'Dan osvoboditve',
'memorial-day' => 'Dan spomina na mrtve',
'mlk-day' => 'Martin Luther King mlajši dan',
'national-day' => 'Dan državnosti',
'new-year' => 'Novo leto',
'new-year-next-day' => 'Novo leto naslednji dan',
'pentecost' => 'Binkoštna nedelja',
'pentecost-monday' => 'Binkoštna ponedeljek',
'preseren-day' => 'Prešernov dan',
'rebellion-day' => 'Dan upora proti okupatorju',
'reformation-day' => 'Dan reformacije',
'royal-day' => 'Kraljevi dan',
'thanksgiving' => 'Dan zahvalnosti',
'toussaint' => 'Toussaint',
'vacation-day' => 'Praznik dela',
'vacation-next-day' => 'Praznik dela naslednji dan',
'victory-1945' => 'Zmaga 1945',
);
14 changes: 7 additions & 7 deletions src/Cmixin/Holidays/fr-national.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

return $date->format('d/m');
},
'labor-day' => '01/05', // Fête du travail
'victory-day' => '08/05', // Victoire 1945
'labor-day' => '01/05', // Fête du travail
'victory-1945' => '08/05', // Victoire 1945
// Ascension
'ascension' => function ($year) {
$days = easter_days($year) + 39;
Expand All @@ -26,9 +26,9 @@

return $date->format('d/m');
},
'national-day' => '14/07', // Fête nationale
'assumption' => '15/08', // Assomption
'toussaint' => '01/11', // Toussaint
'armistice' => '11/11', // Armistice 1918
'christmas' => '25/12', // Noël
'national-day' => '14/07', // Fête nationale
'assumption' => '15/08', // Assomption
'toussaint' => '01/11', // Toussaint
'armistice-1918' => '11/11', // Armistice 1918
'christmas' => '25/12', // Noël
);
4 changes: 2 additions & 2 deletions src/Cmixin/Holidays/nl-national.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@
return $date->format('d/m');
},
// Pinksterzondag
'pentcost' => function ($year) {
'pentecost' => function ($year) {
$days = easter_days($year) + 49;
$date = new DateTime("$year-03-21 +$days days");

return $date->format('d/m');
},
// Pinkstermaandag
'pentcost-monday' => function ($year) {
'pentecost-monday' => function ($year) {
$days = easter_days($year) + 50;
$date = new DateTime("$year-03-21 +$days days");

Expand Down
37 changes: 37 additions & 0 deletions tests/Cmixin/BusinessDayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,43 @@ public function testObserveHolidays()
self::assertFalse($carbon::parse('2018-12-26')->isObservedHoliday());
}

public function testGetHolidayName()
{
$carbon = static::CARBON_CLASS;
$carbon::setLocale('en');
$carbon::setHolidaysRegion('fr-national');
$carbon::setTestNow('2018-12-25');
self::assertSame('en', $carbon::getLocale());
self::assertSame('Christmas', $carbon::getHolidayName());
self::assertSame('National Day', $carbon::getHolidayName(new \DateTime('2018-07-14')));
self::assertSame('Noël', $carbon::getHolidayName('fr'));
$carbon::setTestNow('2018-12-26');
self::assertFalse($carbon::getHolidayName());
self::assertSame('New Year', $carbon::parse('2018-01-01')->getHolidayName());
self::assertSame('Novo leto', $carbon::parse('2018-01-01')->getHolidayName('sl_SI'));
$carbon::setLocale('nl');
self::assertSame('nl', $carbon::getLocale());
self::assertSame('Nieuwjaarsdag', $carbon::parse('2018-01-01')->getHolidayName());
$carbon::setLocale('de'); // Language not translated
self::assertSame('de', $carbon::getLocale());
self::assertSame('New Year', $carbon::parse('2018-01-01')->getHolidayName());
}

public function testGetHolidayNameLocalLocale()
{
$carbon = static::CARBON_CLASS;
$carbon::setLocale('en');
$carbon::setHolidaysRegion('fr-national');
$date = $carbon::parse('2018-01-01');

if (!method_exists($date, 'locale')) {
self::markTestSkipped('Test for Carbon 2 only.');
}

self::assertSame('New Year', $date->getHolidayName());
self::assertSame('Nouvel an', $date->locale('fr')->getHolidayName());
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage You must pass holiday names as a string or "all".
Expand Down

0 comments on commit c12276f

Please sign in to comment.