Skip to content

Commit

Permalink
BrazilExchange
Browse files Browse the repository at this point in the history
  • Loading branch information
felipenoris committed Dec 18, 2018
1 parent 52370c1 commit bb52a1b
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 59 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ This crate provides a set of built-in holiday calendars in the `bdays::calendars

* `bdays::calendars::brazil::BRSettlement` : Brazilian banking holidays

* `bdays::calendars::brazil::BrazilExchange` : BMF&BOVESPA Exchange holidays (http://www.bmfbovespa.com.br)

* `bdays::calendars::us::USSettlement` : United States federal holidays

## Usage

```rust
Expand Down
155 changes: 96 additions & 59 deletions src/calendars/brazil.rs
Original file line number Diff line number Diff line change
@@ -1,77 +1,114 @@

use chrono::Datelike;
use chrono::{Datelike, Weekday};
use HolidayCalendar;
use easter;

/// Brazilian banking holidays.
/// This calendar is defined by brazilian federal holidays plus Carnival.
pub struct BRSettlement;

fn is_brazilian_national_holiday<T: Datelike + Copy + PartialOrd>(date: T) -> bool {

let (yy, mm, dd) = (date.year(), date.month(), date.day());

// Bisection
if mm >= 8 {
// Fixed holidays
if // Independencia do Brasil
((mm == 9) && (dd == 7))
||
// Nossa Senhora Aparecida
((mm == 10) && (dd == 12))
||
// Finados
((mm == 11) && (dd == 2))
||
// Proclamacao da Republica
((mm == 11) && (dd == 15))
||
// Natal
((mm == 12) && (dd == 25))

{
return true
}
} else {
// mm < 8
// Fixed holidays
if
// Confraternizacao Universal
((mm == 1) && (dd == 1))
||
// Tiradentes
((mm == 4) && (dd == 21))
||
// Dia do Trabalho
((mm == 5) && (dd == 1))
{
return true
}

// Easter occurs up to April, so Corpus Christi will be up to July in the worst case, which is before August (mm < 8).
// Holidays based on easter date.
let dt_rata = date.num_days_from_ce();
let e_rata = easter::easter_num_days_from_ce(yy).unwrap();

if
// Segunda de Carnaval
( dt_rata == ( e_rata - 48 ) )
||
// Terca de Carnaval
( dt_rata == ( e_rata - 47 ) )
||
// Sexta-feira Santa
( dt_rata == ( e_rata - 2 ) )
||
// Corpus Christi
( dt_rata == ( e_rata + 60 ) )
{
return true
}
}

false
}

impl<T: Datelike + Copy + PartialOrd> HolidayCalendar<T> for BRSettlement {

fn is_holiday(&self, date: T) -> bool {
is_brazilian_national_holiday(date)
}
}

/// BMF&BOVESPA Exchange holidays (http://www.bmfbovespa.com.br).
pub struct BrazilExchange;

impl<T: Datelike + Copy + PartialOrd> HolidayCalendar<T> for BrazilExchange {

fn is_holiday(&self, date: T) -> bool {

let (yy, mm, dd) = (date.year(), date.month(), date.day());

// Bisection
if mm >= 8 {
// Fixed holidays
if // Independencia do Brasil
((mm == 9) && (dd == 7))
||
// Nossa Senhora Aparecida
((mm == 10) && (dd == 12))
||
// Finados
((mm == 11) && (dd == 2))
||
// Proclamacao da Republica
((mm == 11) && (dd == 15))
||
// Natal
((mm == 12) && (dd == 25))

{
return true
}
} else {
// mm < 8
// Fixed holidays
if
// Confraternizacao Universal
((mm == 1) && (dd == 1))
||
// Tiradentes
((mm == 4) && (dd == 21))
||
// Dia do Trabalho
((mm == 5) && (dd == 1))
{
return true
}

// Easter occurs up to April, so Corpus Christi will be up to July in the worst case, which is before August (mm < 8).
// Holidays based on easter date.
let dt_rata = date.num_days_from_ce();
let e_rata = easter::easter_num_days_from_ce(yy).unwrap();

if
// Segunda de Carnaval
( dt_rata == ( e_rata - 48 ) )
||
// Terca de Carnaval
( dt_rata == ( e_rata - 47 ) )
||
// Sexta-feira Santa
( dt_rata == ( e_rata - 2 ) )
||
// Corpus Christi
( dt_rata == ( e_rata + 60 ) )
{
return true
}
if
// Aniversário de São Paulo
( mm == 1 && dd == 25 )
||
// Revolucão
( mm == 7 && dd == 9 )
||
// Conciência Negra (a partir de 2007)
( yy >= 2007 && mm == 11 && dd == 20 )
// Christmas Eve
||
( mm == 12 && dd == 24)
||
// Último dia útil do ano
( mm == 12 && (dd == 31 || (dd>=29 && date.weekday() == Weekday::Fri) ))
{
return true;
}

false
// national holidays
is_brazilian_national_holiday(date)
}
}
1 change: 1 addition & 0 deletions src/calendars/us.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use chrono::{Datelike, Weekday, NaiveDate, Duration};
use HolidayCalendar;
use easter;

/// United States federal holidays.
pub struct USSettlement;

fn end_of_month(mut yy: i32, mut mm: u32) -> NaiveDate {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
//!
//! * `bdays::calendars::WeekendsOnly` : accounts only weekends
//! * `bdays::calendars::brazil::BRSettlement` : Brazilian banking holidays
//! * `bdays::calendars::brazil::BrazilExchange` : BMF&BOVESPA Exchange holidays (http://www.bmfbovespa.com.br)
//! * `bdays::calendars::us::USSettlement` : United States federal holidays
//!
//! # Usage
//!
Expand Down
13 changes: 13 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,3 +551,16 @@ fn test_us_settlement_cached() {
let cal = HolidayCalendarCache::new(calendars::us::USSettlement, d0, d1);
us_settlement_tests(cal);
}

#[test]
fn test_brazil_exchange() {
let cal = calendars::brazil::BrazilExchange;

assert!(!cal.is_bday(NaiveDate::from_ymd(2017, 11, 19))); // Sunday
assert!(!cal.is_bday(NaiveDate::from_ymd(2017, 11, 20))); //Conciência Negra (segunda)
assert!(cal.is_bday(NaiveDate::from_ymd(2017, 11, 21))); // Tuesday

assert!(cal.is_bday(NaiveDate::from_ymd(2013, 5, 29))); // wednesday
assert!(!cal.is_bday(NaiveDate::from_ymd(2013, 5, 30))); // Corpus Christi (National Holiday)
assert!(cal.is_bday(NaiveDate::from_ymd(2013, 5, 31))); // friday
}

0 comments on commit bb52a1b

Please sign in to comment.