Skip to content

Commit

Permalink
Start of month functions (#2034)
Browse files Browse the repository at this point in the history
  • Loading branch information
lballabio authored Jul 29, 2024
2 parents 2230bcc + 0d13eb2 commit 826075f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
16 changes: 15 additions & 1 deletion ql/time/calendar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ namespace QuantLib {
weekend for the given market.
*/
bool isWeekend(Weekday w) const;
/*! Returns <tt>true</tt> iff in the given market, the date is on
or before the first business day for that month.
*/
bool isStartOfMonth(const Date& d) const;
//! first business day of the month to which the given date belongs
Date startOfMonth(const Date& d) const;
/*! Returns <tt>true</tt> iff in the given market, the date is on
or after the last business day for that month.
*/
Expand Down Expand Up @@ -240,8 +246,16 @@ namespace QuantLib {
return impl_->isBusinessDay(_d);
}

inline bool Calendar::isStartOfMonth(const Date& d) const {
return d <= startOfMonth(d);
}

inline Date Calendar::startOfMonth(const Date& d) const {
return adjust(Date::startOfMonth(d), Following);
}

inline bool Calendar::isEndOfMonth(const Date& d) const {
return (d.month() != adjust(d+1).month());
return d >= endOfMonth(d);
}

inline Date Calendar::endOfMonth(const Date& d) const {
Expand Down
16 changes: 15 additions & 1 deletion ql/time/date.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ namespace QuantLib {
static Date maxDate();
//! whether the given year is a leap one
static bool isLeap(Year y);
//! first day of the month to which the given date belongs
static Date startOfMonth(const Date& d);
//! whether a date is the first day of its month
static bool isStartOfMonth(const Date& d);
//! last day of the month to which the given date belongs
static Date endOfMonth(const Date& d);
//! whether a date is the last day of its month
Expand Down Expand Up @@ -389,9 +393,19 @@ namespace QuantLib {

#endif

#ifndef QL_HIGH_RESOLUTION_DATE
// inline definitions

inline Date Date::startOfMonth(const Date& d) {
Month m = d.month();
Year y = d.year();
return Date(1, m, y);
}

inline bool Date::isStartOfMonth(const Date& d) {
return (d.dayOfMonth() == 1);
}

#ifndef QL_HIGH_RESOLUTION_DATE
inline Weekday Date::weekday() const {
Integer w = serialNumber_ % 7;
return Weekday(w == 0 ? 7 : w);
Expand Down
30 changes: 30 additions & 0 deletions test-suite/calendars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3369,6 +3369,31 @@ BOOST_AUTO_TEST_CASE(testMexicoInaugurationDay) {
}
}

BOOST_AUTO_TEST_CASE(testStartOfMonth) {
BOOST_TEST_MESSAGE("Testing start-of-month calculation...");

Calendar c = TARGET(); // any calendar would be OK

Date som, counter = Date::minDate() + 2 * Months;
Date last = Date::maxDate();

while (counter < last) {
som = c.startOfMonth(counter);
// check that som is som
if (!c.isStartOfMonth(som))
BOOST_FAIL("\n " << som.weekday() << " " << som << " is not the first business day in "
<< som.month() << " " << som.year() << " according to " << c.name());
// check that som is in the same month as counter
if (som.month() != counter.month())
BOOST_FAIL("\n " << som << " is not in the same month as " << counter);
// Check that previous business day is in a different month
if (c.advance(som, -1, Days, Unadjusted).month() == som.month())
BOOST_FAIL("\n " << c.advance(som, -1, Days, Unadjusted)
<< " is in the same month as "
<< som);
counter = counter + 1;
}
}

BOOST_AUTO_TEST_CASE(testEndOfMonth) {
BOOST_TEST_MESSAGE("Testing end-of-month calculation...");
Expand All @@ -3387,6 +3412,11 @@ BOOST_AUTO_TEST_CASE(testEndOfMonth) {
// check that eom is in the same month as counter
if (eom.month() != counter.month())
BOOST_FAIL("\n " << eom << " is not in the same month as " << counter);
// Check that next business day is in a different month
if (c.advance(eom, 1, Days, Unadjusted).month() == eom.month())
BOOST_FAIL("\n " << c.advance(eom, 1, Days, Unadjusted)
<< " is in the same month as "
<< eom);
counter = counter + 1;
}
}
Expand Down

0 comments on commit 826075f

Please sign in to comment.