Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,9 @@
<testsuite name="USA">
<directory>./tests/USA</directory>
</testsuite>
<!-- Test Suite for holidays and closures of the New York Stock Exchange (NYSE) in United States -->
<testsuite name="NYSE">
<directory>./tests/USA/NYSE</directory>
</testsuite>
</testsuites>
</phpunit>
1 change: 1 addition & 0 deletions src/Yasumi/Provider/Brazil.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ protected function calculateProclamationOfRepublicDay(): void
'proclamationOfRepublicDay',
['pt' => 'Dia da Proclamação da República'],
new \DateTime("{$this->year}-11-15", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
$this->locale
));
}
}
Expand Down
107 changes: 107 additions & 0 deletions src/Yasumi/Provider/USA/NYSE.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types = 1);

/**
* This file is part of the 'Yasumi' package.
*
* The easy PHP Library for calculating holidays.
*
* Copyright (c) 2015 - 2025 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <me at sachatelgenhof dot com>
* @author Art Kurbakov <admin at mgwebgroup dot com>
*/

// This file in addition to regular holidays observed by
// the New York Stock Exchange (NYSE),
// includes full day special closure events due to:
// weather, national emergencies and presidential proclamations.
// All closure events are included from year 2000.

namespace Yasumi\Provider\USA;

use Yasumi\Holiday;
use Yasumi\Provider\USA;

class NYSE extends USA
{
/**
* Initialize holidays for the NYSE.
*
* @throws \Exception
*/
public function initialize(): void
{
$this->timezone = 'America/New_York';

// Add exchange-specific holidays
$this->addHoliday($this->newYearsDay($this->year, $this->timezone, $this->locale));
$this->calculateMartinLutherKingday();
$this->calculateWashingtonsBirthday();
$this->addHoliday($this->goodFriday($this->year, $this->timezone, $this->locale));
$this->calculateMemorialDay();
if (2021 < $this->year) {
$this->calculateJuneteenth();
}
$this->calculateIndependenceDay();
$this->calculateLabourDay();
$this->calculateThanksgivingDay();
$this->addHoliday($this->christmasDay($this->year, $this->timezone, $this->locale));

$this->calculateSubstituteHolidays();

// Add other full-day closure events
$this->addWeatherEvents();
$this->addEmergencies();
$this->addProclamations();
}

public function getSources(): array
{
return [
'https://www.nyse.com/trader-update/history#11507',
'https://s3.amazonaws.com/armstrongeconomics-wp/2013/07/NYSE-Closings.pdf',
'https://ir.theice.com/press/news-details/2018/New-York-Stock-Exchange-to-Honor-President-George-H-W-Bush/default.aspx',
'https://ir.theice.com/press/news-details/2024/The-New-York-Stock-Exchange-Will-Close-Markets-on-January-9-to-Honor-the-Passing-of-Former-President-Jimmy-Carter-on-National-Day-of-Mourning/default.aspx',
'https://www.thecorporatecounsel.net/blog/2021/10/nyse-makes-juneteenth-a-new-market-holiday.html',
];
}

private function addWeatherEvents()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is missing a return type (void).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added void return type.

{
if (2012 == $this->year) {
$this->addHoliday(new Holiday('hurricaneSandy1', [], new \DateTime('2012-10-29', new \DateTimeZone($this->timezone))));
$this->addHoliday(new Holiday('hurricaneSandy2', [], new \DateTime('2012-10-30', new \DateTimeZone($this->timezone))));
}
}

private function addEmergencies()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is missing a return type (void).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added void return type.

{
if (2001 == $this->year) {
$this->addHoliday(new Holiday('groundZero1', [], new \DateTime('2001-09-11', new \DateTimeZone($this->timezone))));
$this->addHoliday(new Holiday('groundZero2', [], new \DateTime('2001-09-12', new \DateTimeZone($this->timezone))));
$this->addHoliday(new Holiday('groundZero3', [], new \DateTime('2001-09-13', new \DateTimeZone($this->timezone))));
$this->addHoliday(new Holiday('groundZero4', [], new \DateTime('2001-09-14', new \DateTimeZone($this->timezone))));
}
}

private function addProclamations()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is missing a return type (void).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added void return type.

{
if (2004 == $this->year) {
$this->addHoliday(new Holiday('ReaganMourning', [], new \DateTime('2004-06-11', new \DateTimeZone($this->timezone))));
}
if (2007 == $this->year) {
$this->addHoliday(new Holiday('GRFordMourning', [], new \DateTime('2007-01-02', new \DateTimeZone($this->timezone))));
}
if (2018 == $this->year) {
$this->addHoliday(new Holiday('HWBushMourning', [], new \DateTime('2018-12-05', new \DateTimeZone($this->timezone))));
}
if (2025 == $this->year) {
$this->addHoliday(new Holiday('CarterMourning', [], new \DateTime('2025-01-09', new \DateTimeZone($this->timezone))));
}
}
}
80 changes: 80 additions & 0 deletions tests/USA/NYSE/CarterMourningTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types = 1);

/**
* This file is part of the 'Yasumi' package.
*
* The easy PHP Library for calculating holidays.
*
* Copyright (c) 2015 - 2025 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <me at sachatelgenhof dot com>
* @author Art Kurbakov <admin at mgwebgroup dot com>
*/

namespace Yasumi\tests\USA\NYSE;

use Yasumi\tests\USA\USABaseTestCase;

/**
* Class to test day of closure of NYSE due to Jimmy Carter mourning proclamation
*/
class CarterMourningTest extends USABaseTestCase
{
/**
* Name of provider to be tested.
*/
public const REGION = 'USA/NYSE';

/**
* The year when the closure was observed.
*/
public const OBSERVED_YEAR = 2025;

/**
* Tests day of closure on January 9th 2025
*
* @throws \Exception
*/
public function testCarterMourning(): void
{
$this->assertHoliday(
self::REGION,
'CarterMourning',
self::OBSERVED_YEAR,
new \DateTime('2025-01-09', new \DateTimeZone(self::TIMEZONE))
);
}

/**
* Tests years before 2025
*
* @throws \Exception
*/
public function testCarterMourningBefore2025(): void
{
$this->assertNotHoliday(
self::REGION,
'CarterMourning',
self::OBSERVED_YEAR - 1
);
}

/**
* Tests years after 2025
*
* @throws \Exception
*/
public function testCarterMourningAfter2025(): void
{
$this->assertNotHoliday(
self::REGION,
'CarterMourning',
self::OBSERVED_YEAR + 1
);
}
}
80 changes: 80 additions & 0 deletions tests/USA/NYSE/GRFordMourningTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types = 1);

/**
* This file is part of the 'Yasumi' package.
*
* The easy PHP Library for calculating holidays.
*
* Copyright (c) 2015 - 2025 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <me at sachatelgenhof dot com>
* @author Art Kurbakov <admin at mgwebgroup dot com>
*/

namespace Yasumi\tests\USA\NYSE;

use Yasumi\tests\USA\USABaseTestCase;

/**
* Class to test day of closure of NYSE due to G.R. Ford Mourning proclamation
*/
class GRFordMourningTest extends USABaseTestCase
{
/**
* Name of provider to be tested.
*/
public const REGION = 'USA/NYSE';

/**
* The year when the closure was observed.
*/
public const OBSERVED_YEAR = 2007;

/**
* Tests day of closure on January 2nd 2007
*
* @throws \Exception
*/
public function testGRFordMourning(): void
{
$this->assertHoliday(
self::REGION,
'GRFordMourning',
self::OBSERVED_YEAR,
new \DateTime('2007-01-02', new \DateTimeZone(self::TIMEZONE))
);
}

/**
* Tests years before 2007
*
* @throws \Exception
*/
public function testGRFordMourningBefore2007(): void
{
$this->assertNotHoliday(
self::REGION,
'GRFordMourning',
self::OBSERVED_YEAR - 1
);
}

/**
* Tests years after 2007
*
* @throws \Exception
*/
public function testGRFordMourningAfter2007(): void
{
$this->assertNotHoliday(
self::REGION,
'GRFordMourning',
self::OBSERVED_YEAR + 1
);
}
}
Loading