-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.


{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Time.EN.US.Rules where

import Data.Maybe
import Prelude

import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Regex.Types
import Duckling.Time.Computed
import Duckling.Time.Helpers
import Duckling.Time.Types (TimeData (..))
import Duckling.Types
import qualified Duckling.Time.Types as TTime
import qualified Duckling.TimeGrain.Types as TG

ruleMMDD :: Rule
ruleMMDD :: Rule
ruleMMDD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"mm/dd"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(1[0-2]|0?[1-9])\\s?[/-]\\s?(3[01]|[12]\\d|0?[1-9])"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (mm:dd:_)):[Token]
_) -> do
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        Int
d <- Text -> Maybe Int
parseInt Text
dd
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
monthDay Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMMDDYYYY :: Rule
ruleMMDDYYYY :: Rule
ruleMMDDYYYY = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"mm/dd/yyyy"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(1[0-2]|0?[1-9])[-/\\s](3[01]|[12]\\d|0?[1-9])[-/\\s](\\d{2,4})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (mm:dd:yy:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        Int
d <- Text -> Maybe Int
parseInt Text
dd
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- Clashes with HHMMSS, hence only 4-digit years
ruleMMDDYYYYDot :: Rule
ruleMMDDYYYYDot :: Rule
ruleMMDDYYYYDot = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"mm.dd.yyyy"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(1[0-2]|0?[1-9])\\.(3[01]|[12]\\d|0?[1-9])\\.(\\d{4})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (mm:dd:yy:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        Int
d <- Text -> Maybe Int
parseInt Text
dd
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleBackwardCompatibleHolidays :: [Rule]
ruleBackwardCompatibleHolidays :: [Rule]
ruleBackwardCompatibleHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ (Text
"Thanksgiving Day", String
"thanks?giving( day)?", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
4 Int
4 Int
11)
  , (Text
"Father's Day", String
"father'?s?'? day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
7 Int
6)
  ]

rulePeriodicHolidays :: [Rule]
rulePeriodicHolidays :: [Rule]
rulePeriodicHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  -- Fixed dates, year over year
  [ ( Text
"African Liberation Day", String
"african liberation day", Int -> Int -> TimeData
monthDay Int
5 Int
25 )
  , ( Text
"Air Force Birthday", String
"air force birthday", Int -> Int -> TimeData
monthDay Int
9 Int
18 )
  , ( Text
"Alaska Day", String
"alaska day", Int -> Int -> TimeData
monthDay Int
10 Int
18 )
  , ( Text
"American Eagle Day", String
"american eagle day", Int -> Int -> TimeData
monthDay Int
6 Int
20 )
  , ( Text
"Army Birthday", String
"army birthday", Int -> Int -> TimeData
monthDay Int
6 Int
14 )
  , ( Text
"Bennington Battle Day", String
"bennington battle day", Int -> Int -> TimeData
monthDay Int
8 Int
16 )
  , ( Text
"Bunker Hill Day", String
"bunker hill day", Int -> Int -> TimeData
monthDay Int
6 Int
17 )
  , ( Text
"California Admission Day", String
"california admission day", Int -> Int -> TimeData
monthDay Int
9 Int
9 )
  , ( Text
"Cinco de Mayo", String
"cinco de mayo", Int -> Int -> TimeData
monthDay Int
5 Int
5 )
  , ( Text
"Citizenship Day", String
"citizenship day|i am an american day", Int -> Int -> TimeData
monthDay Int
9 Int
17 )
  , ( Text
"Coast Guard Birthday", String
"coast guard (birth)?day", Int -> Int -> TimeData
monthDay Int
8 Int
4 )
  , ( Text
"Colorado Day", String
"colorado day", Int -> Int -> TimeData
monthDay Int
8 Int
1 )
  , ( Text
"Constitution Day and Citizenship Day", String
"constitution day and citizenship day", Int -> Int -> TimeData
monthDay Int
9 Int
17 )
  , ( Text
"César Chávez Day", String
"c[ée]sar ch[áa]vez day", Int -> Int -> TimeData
monthDay Int
3 Int
31 )
  , ( Text
"D-Day", String
"d\\-day", Int -> Int -> TimeData
monthDay Int
6 Int
6 )
  , ( Text
"Day After Christmas Day", String
"day after christmas day", Int -> Int -> TimeData
monthDay Int
12 Int
26 )
  , ( Text
"Elizabeth Peratrovich Day", String
"elizabeth peratrovich day", Int -> Int -> TimeData
monthDay Int
2 Int
16 )
  , ( Text
"Evacuation Day", String
"evacuation day", Int -> Int -> TimeData
monthDay Int
3 Int
17 )
  , ( Text
"Father Damien Day", String
"father damien day", Int -> Int -> TimeData
monthDay Int
4 Int
15 )
  , ( Text
"Feast of Our Lady of Guadalupe", String
"feast of our lady of guadalupe", Int -> Int -> TimeData
monthDay Int
12 Int
12 )
  , ( Text
"Flag Day", String
"flag day", Int -> Int -> TimeData
monthDay Int
6 Int
14 )
  , ( Text
"Groundhog Day", String
"groundhogs? day", Int -> Int -> TimeData
monthDay Int
2 Int
2 )
  , ( Text
"Harvey Milk Day", String
"harvey milk day", Int -> Int -> TimeData
monthDay Int
5 Int
22 )
  , ( Text
"Inauguration Day", String
"inauguration day", Int -> Int -> TimeData
monthDay Int
1 Int
20 )
  , ( Text
"Independence Day", String
"independence day", Int -> Int -> TimeData
monthDay Int
7 Int
4 )
  , ( Text
"Juneteenth", String
"juneteenth", Int -> Int -> TimeData
monthDay Int
6 Int
19 )
  , ( Text
"Kamehameha Day", String
"kamehameha day", Int -> Int -> TimeData
monthDay Int
6 Int
11 )
  , ( Text
"Kansas Day", String
"kansas day", Int -> Int -> TimeData
monthDay Int
1 Int
29 )
  , ( Text
"Kent State Shootings Remembrance", String
"kent state shootings remembrance", Int -> Int -> TimeData
monthDay Int
5 Int
4 )
  , ( Text
"Loyalty Day", String
"l(aw|ei|oyalty) day", Int -> Int -> TimeData
monthDay Int
5 Int
1 )
  , ( Text
"Leif Erikson Day", String
"leif erikson day", Int -> Int -> TimeData
monthDay Int
10 Int
9 )
  , ( Text
"Lincoln's Birthday", String
"(abraham )?lincoln'?s?'? birthday", Int -> Int -> TimeData
monthDay Int
2 Int
12 )
  , ( Text
"Linus Pauling Day", String
"linus pauling day", Int -> Int -> TimeData
monthDay Int
2 Int
28 )
  , ( Text
"Lyndon Baines Johnson Day", String
"lyndon baines johnson day", Int -> Int -> TimeData
monthDay Int
8 Int
27 )
  , ( Text
"Marine Corps Birthday", String
"marine corps (birth)?day", Int -> Int -> TimeData
monthDay Int
11 Int
10 )
  , ( Text
"Maryland Day", String
"maryland day", Int -> Int -> TimeData
monthDay Int
3 Int
25 )
  , ( Text
"National Aviation Day", String
"national aviation day", Int -> Int -> TimeData
monthDay Int
8 Int
19 )
  , ( Text
"National Freedom Day", String
"national freedom day", Int -> Int -> TimeData
monthDay Int
2 Int
1 )
  , ( Text
"National Guard Birthday", String
"national guard (birth)?day", Int -> Int -> TimeData
monthDay Int
12 Int
13 )
  , ( Text
"National Korean War Veterans Armistice Day", String
"national korean war veterans armistice day", Int -> Int -> TimeData
monthDay Int
7 Int
27 )
  , ( Text
"National Maritime Day", String
"national maritime day", Int -> Int -> TimeData
monthDay Int
5 Int
22 )
  , ( Text
"National Missing Children's Day", String
"national missing children'?s day", Int -> Int -> TimeData
monthDay Int
5 Int
25 )
  , ( Text
"National Nurses Day", String
"national nurses day", Int -> Int -> TimeData
monthDay Int
5 Int
6 )
  , ( Text
"National Tartan Day", String
"national tartan day", Int -> Int -> TimeData
monthDay Int
4 Int
6 )
  , ( Text
"Navy Birthday", String
"(u\\.?s\\.? )?navy (birth)?day", Int -> Int -> TimeData
monthDay Int
10 Int
13 )
  , ( Text
"Oklahoma Day", String
"oklahoma day", Int -> Int -> TimeData
monthDay Int
4 Int
22 )
  , ( Text
"Pan American Aviation Day", String
"pan american aviation day", Int -> Int -> TimeData
monthDay Int
12 Int
17 )
  , ( Text
"Pascua Florida Day", String
"pascua florida day", Int -> Int -> TimeData
monthDay Int
4 Int
2 )
  , ( Text
"Patriot Day", String
"patriot day", Int -> Int -> TimeData
monthDay Int
9 Int
11 )
  , ( Text
"Peace Officers Memorial Day", String
"peace officers memorial day", Int -> Int -> TimeData
monthDay Int
5 Int
15 )
  , ( Text
"Pearl Harbor Remembrance Day", String
"pearl harbor remembrance day", Int -> Int -> TimeData
monthDay Int
12 Int
7 )
  , ( Text
"Pioneer Day", String
"pioneer day", Int -> Int -> TimeData
monthDay Int
7 Int
24 )
  , ( Text
"Prince Jonah Kuhio Kalanianaole Day", String
"prince jonah kuhio kalanianaole day", Int -> Int -> TimeData
monthDay Int
3 Int
26 )
  , ( Text
"Purple Heart Day", String
"purple heart day", Int -> Int -> TimeData
monthDay Int
8 Int
7 )
  , ( Text
"Read Across America Day", String
"read across america day", Int -> Int -> TimeData
monthDay Int
3 Int
2 )
  , ( Text
"Rhode Island Independence Day", String
"rhode island independence day", Int -> Int -> TimeData
monthDay Int
5 Int
4 )
  , ( Text
"Rosa Parks Day", String
"rosa parks day", Int -> Int -> TimeData
monthDay Int
2 Int
4 )
  , ( Text
"San Jacinto Day", String
"san jacinto day", Int -> Int -> TimeData
monthDay Int
4 Int
21 )
  , ( Text
"Self-Injury Awareness Day", String
"self\\-injury awareness day", Int -> Int -> TimeData
monthDay Int
3 Int
1 )
  , ( Text
"Senior Citizens Day", String
"senior citizens day", Int -> Int -> TimeData
monthDay Int
8 Int
21 )
  , ( Text
"Siblings Day", String
"(national )?sibling'?s?'? day", Int -> Int -> TimeData
monthDay Int
4 Int
10 )
  , ( Text
"St Nicholas' Day", String
"st\\.? nicholas'? day", Int -> Int -> TimeData
monthDay Int
12 Int
6 )
  , ( Text
"St. David's Day", String
"st\\.? david'?s day", Int -> Int -> TimeData
monthDay Int
3 Int
1 )
  , ( Text
"Statehood Day", String
"statehood day", Int -> Int -> TimeData
monthDay Int
6 Int
1 )
  , ( Text
"Statehood Day in Arizona", String
"statehood day in arizona", Int -> Int -> TimeData
monthDay Int
2 Int
14 )
  , ( Text
"Stephen Foster Memorial Day", String
"stephen foster memorial day", Int -> Int -> TimeData
monthDay Int
1 Int
13 )
  , ( Text
"Susan B Anthony's Birthday", String
"susan b\\.? anthony'?s birthday", Int -> Int -> TimeData
monthDay Int
2 Int
15 )
  , ( Text
"Texas Independence Day", String
"texas independence day", Int -> Int -> TimeData
monthDay Int
3 Int
2 )
  , ( Text
"Thomas Jefferson's Birthday", String
"thomas jefferson'?s birthday", Int -> Int -> TimeData
monthDay Int
4 Int
13 )
  , ( Text
"Truman Day", String
"truman day", Int -> Int -> TimeData
monthDay Int
5 Int
8 )
  , ( Text
"Veterans Day", String
"veterans? day", Int -> Int -> TimeData
monthDay Int
11 Int
11 )
  , ( Text
"West Virginia Day", String
"west virginia day", Int -> Int -> TimeData
monthDay Int
6 Int
20 )
  , ( Text
"White Cane Safety Day", String
"white cane safety day", Int -> Int -> TimeData
monthDay Int
10 Int
15 )
  , ( Text
"Women's Equality Day", String
"women'?s equality day", Int -> Int -> TimeData
monthDay Int
8 Int
26 )
  , ( Text
"Wright Brothers Day", String
"wright brothers day", Int -> Int -> TimeData
monthDay Int
12 Int
17 )

  -- Fixed day/week/month, year over year
  , ( Text
"Arbor Day", String
"arbor day", TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
5) (Int -> TimeData
month Int
4) )
  , ( Text
"Armed Forces Day", String
"armed forces day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
6 Int
5 )
  , ( Text
"Casimir Pulaski Day", String
"casimir pulaski day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
3 )
  , ( Text
"Child Health Day", String
"child health day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
10 )
  , ( Text
"Columbus Day", String
"columbus day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
1 Int
10 )
  , ( Text
"Daylight Saving Start Day", String
"daylight savings? start( day)?", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
7 Int
3 )
  , ( Text
"Daylight Saving End Day", String
"daylight savings? end( day)?", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
7 Int
11 )

  -- Saturday after Labor Day
  , ( Text
"Carl Garner Federal Lands Cleanup Day"
    , String
"carl garner federal lands cleanup day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
5 (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
9 )
  -- Monday after Thanksgiving
  , ( Text
"Cyber Monday", String
"cyber monday"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
4 (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
4 Int
4 Int
11 )
  , ( Text
"Election Day", String
"election day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
1 (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
11 )
  , ( Text
"Employee Appreciation Day", String
"employee appreciation day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
5 Int
3 )
  , ( Text
"Friendship Day", String
"friendship day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
7 Int
8 )
  , ( Text
"Gold Star Mother's Day", String
"gold star mother's day"
    , TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
7) (Int -> TimeData
month Int
9) )
  , ( Text
"Indigenous People's Day", String
"indigenous people's day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
1 Int
10 )
  , ( Text
"Labor Day", String
"labor day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
9 )
  -- Long weekend before the first Monday of September
  , ( Text
"Labor Day weekend", String
"labor day week(\\s|-)?ends?"
    , TimeData -> TimeData
longWEBefore (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
9
    )
  , ( Text
"Lee Jackson Day", String
"lee jackson day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
5 Int
1 )
  -- Last Monday of May
  , ( Text
"Memorial Day", String
"(decoration|memorial) day"
    , TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
1) (Int -> TimeData
month Int
5) )
  -- Long weekend before the last Monday of May
  , ( Text
"Memorial Day weekend", String
"(decoration|memorial) day week(\\s|-)?ends?"
    , TimeData -> TimeData
longWEBefore (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
1) (Int -> TimeData
month Int
5) )
  -- 2 days before Mother's Day
  , ( Text
"Military Spouse Day", String
"military spouse (appreciation )?day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (- Int
2) (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
7 Int
5 )
  , ( Text
"Mother's Day", String
"mother'?s?'? day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
7 Int
5 )
  , ( Text
"National CleanUp Day", String
"national clean\\-?up day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
6 Int
9 )
  , ( Text
"National Day of Prayer", String
"national day of prayer", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
4 Int
5 )
  , ( Text
"National Defense Transportation Day"
    , String
"national defense transportation day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
5 Int
5 )
  , ( Text
"National Explosive Ordnance Disposal Day"
    , String
"national (eod|explosive ordnance disosal) day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
6 Int
5 )
  -- First Sunday after Labor Day
  , ( Text
"National Grandparents Day", String
"national grandparents day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
6 (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
1 Int
9 )
  , ( Text
"National POW/MIA Recognition Day", String
"national pow/mia recognition day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
5 Int
9 )
  , ( Text
"National Wear Red Day", String
"national wear red day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
5 Int
2 )
  -- Day after Thanksgiving
  , ( Text
"Native American Heritage Day"
    , String
"(american indian|native american) heritage day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
1 (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
4 Int
4 Int
11 )
  , ( Text
"Native Americans' Day", String
"native americans' day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
4 Int
1 Int
9 )
  , ( Text
"Nevada Day", String
"nevada day", TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
5) (Int -> TimeData
month Int
10) )
  , ( Text
"Parents' Day", String
"parents' day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
4 Int
7 Int
7 )
  , ( Text
"Patriots' Day", String
"patriot'?s'? day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
1 Int
4 )
  , ( Text
"Robert E. Lee Day", String
"robert e\\. lee day|lee's (birth)?day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
1 Int
1 )
  , ( Text
"Seward's Day", String
"seward's day", TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
1) (Int -> TimeData
month Int
3) )
  , ( Text
"Statehood Day", String
"(admission|statehood) day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
5 Int
8 )
  , ( Text
"Sweetest Day", String
"sweetest day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
6 Int
10 )
  , ( Text
"Take our Daughters and Sons to Work Day"
    , String
"take our daughters and sons to work day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
4 Int
4 Int
4 )
  , ( Text
"Town Meeting Day", String
"town meeting day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
1 Int
2 Int
3 )
  , ( Text
"Victory Day", String
"victory day", Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
2 Int
1 Int
8 )
  , ( Text
"President's Day"
    , String
"(george )?washington'?s? (birth)?day|president'?s?'? day|daisy gatson bates'? day"
    , Int -> Int -> Int -> TimeData
nthDOWOfMonth Int
3 Int
1 Int
2
    )

  -- Wednesday of the last full week of April, where a full week starts on
  -- Sunday and ends on Saturday.
  , ( Text
"Administrative Professionals' Day"
    , String
"(administrative professional|secretarie|admin)('?s'?)? day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
3) (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$
        Int -> TimeData -> TimeData -> TimeData
predNthAfter (-Int
1) (Int -> TimeData
dayOfWeek Int
6) (Int -> Int -> TimeData
monthDay Int
5 Int
1) )
  -- Wednesday of the 3rd full week in May, starting on a Sunday
  , ( Text
"Emergency Medical Services for Children Day"
    , String
"(national )?(emsc|emergency medical services for children) day"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
3 (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData -> TimeData -> TimeData
predNthAfter Int
2 (Int -> TimeData
dayOfWeek Int
7) (Int -> Int -> TimeData
monthDay Int
5 Int
1)
    )

  -- Other
  , ( Text
"Emancipation Day", String
"emancipation day"
    , Int -> TimeData -> TimeData -> TimeData
predNthClosest Int
0 TimeData
weekday (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
monthDay Int
4 Int
16 )
  ]

rulePeriodicHolidays' :: [Rule]
rulePeriodicHolidays' :: [Rule]
rulePeriodicHolidays' = [(Text, String, Maybe TimeData)] -> [Rule]
mkRuleHolidays'
  -- Fixed dates, year over year
  [ ( Text
"Kwanzaa", String
"kwanzaa", TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Int -> Int -> TimeData
monthDay Int
12 Int
26) (Int -> Int -> TimeData
monthDay Int
1 Int
1) )

  -- 3rd full week in May, starting on a Sunday
  , ( Text
"Emergency Medical Services Week"
    , String
"(national )?(ems|emergency medical services) week"
    , let start :: TimeData
start = Int -> TimeData -> TimeData -> TimeData
predNthAfter Int
2 (Int -> TimeData
dayOfWeek Int
7) (Int -> Int -> TimeData
monthDay Int
5 Int
1)
          end :: TimeData
end = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
6 TimeData
start
      in TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end )

  -- Other
  -- First weekday on or after April 15 if different than Emancipation Day
  -- Otherwise, first weekday following Emancipation Day
  , ( Text
"Tax Day", String
"tax day"
    , let emancipationDay :: TimeData
emancipationDay = Int -> TimeData -> TimeData -> TimeData
predNthClosest Int
0 TimeData
weekday (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
monthDay Int
4 Int
16
          tentative :: TimeData
tentative = Int -> TimeData -> TimeData -> TimeData
predNthAfter Int
0 TimeData
weekday (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
monthDay Int
4 Int
15
          alternative :: TimeData
alternative = Int -> TimeData -> TimeData -> TimeData
predNthAfter Int
1 TimeData
weekday TimeData
emancipationDay
      in TimeData -> TimeData -> TimeData -> Maybe TimeData
intersectWithReplacement TimeData
emancipationDay TimeData
tentative TimeData
alternative )
  ]

-- duplicating "Tuesday" regex as we lost the internal info
tuesday :: String
tuesday :: String
tuesday = String
"(tuesdays?|tue?\\.?)"

ruleComputedHolidays :: [Rule]
ruleComputedHolidays :: [Rule]
ruleComputedHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ ( Text
"Super Tuesday", String
"super\\s+" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tuesday, TimeData
superTuesday )
  , ( Text
"Mini-Tuesday"
    , String
"mini(\\s*\\-\\s*|\\s+)" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tuesday
    , Int -> Int -> Int -> TimeData
yearMonthDay Int
2004 Int
2 Int
3
    )
  , ( Text
"Super Tuesday"
    , String
"((mega\\s+)?giga|tsunami|super\\s+duper)\\s+" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tuesday
    , Int -> Int -> Int -> TimeData
yearMonthDay Int
2008 Int
2 Int
5
    )
  ]

ruleComputedHolidays' :: [Rule]
ruleComputedHolidays' :: [Rule]
ruleComputedHolidays' = [(Text, String, Maybe TimeData)] -> [Rule]
mkRuleHolidays'
  [ ( Text
"Global Youth Service Day", String
"national youth service day"
    , let start :: TimeData
start = TimeData
globalYouthServiceDay
          end :: TimeData
end = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
2 TimeData
globalYouthServiceDay
        in TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end )
  ]

rulesBackwardCompatible :: [Rule]
rulesBackwardCompatible :: [Rule]
rulesBackwardCompatible =
  [ Rule
ruleMMDD
  , Rule
ruleMMDDYYYY
  , Rule
ruleMMDDYYYYDot
  ]
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleBackwardCompatibleHolidays

rules :: [Rule]
rules :: [Rule]
rules = [Rule]
rulesBackwardCompatible
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleComputedHolidays
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleComputedHolidays'
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
rulePeriodicHolidays
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
rulePeriodicHolidays'