
Hi folks,
 
I was trying to use the GBBankHoliday() function and found that it only returns one date for any year, unlike, say, holidayNYSE() that seems to be quite comprehensive. (I’m using R2.11.1 and timeDate_2130.91). 
 
So I wrote up the following function (referring to Wikipedia for the history of English Bank Holidays). Would you care to validate? If it’s okay, or after you improve it for performance/readability, if you’d like to publish it in timeDate, please go ahead.
 
I welcome your feedback.

Thanks,
 
Murali
 
GBBankHoliday <- function (year = getRmetricsOptions("currentYear")) 
{
    holidays <- NULL
    for (y in year) {
        if (y >= 1834 & y < 1870) {
            # 1 May, 1 November, Good Friday and Christmas are the only England Bank Holidays
            dts <- c(paste(y, "-05-01", sep = ""), paste(y, "-11-01", sep = ""))
            holidays <- c(holidays, dts, as.character(GoodFriday(y)), as.character(ChristmasDay(y))) 
        } else {
            # Good Friday and Easter Monday
            holidays <- c(holidays, as.character(GoodFriday(y)), as.character(EasterMonday(y)))
            if (y <= 1964) {
                # Whit Monday, which is exactly 50 days after Easter
                holidays <- c(holidays, as.character(Easter(y, 50)))
                # First Monday in August
                lon <- timeDate(.on.or.after(y, 8, 1, 1), zone = "London", FinCenter = "Europe/London")
                holidays <- c(holidays, as.character(lon))
            } else {
                # Last Monday in May replaces Whit Monday
                if (y == 2002) {
                    # Last Monday in May holiday moved to June 3, and Queen's Jubilee on June 4
                    dts <- c(paste(y, "-06-03", sep = ""), paste(y, "-06-04", sep = ""))
                    holidays <- c(holidays, dts)    
                } else if (y == 2012) {
                    # Last Monday in May holiday moved to June 4, and Queen's Diamond Jubilee on June 5
                    dts <- c(paste(y, "-06-04", sep = ""), paste(y, "-06-05", sep = ""))
                    holidays <- c(holidays, dts)
                } else {
                    lon <- timeDate(.last.of.nday(y, 5, 31, 1), zone = "London", FinCenter = "Europe/London")
                    holidays <- c(holidays, as.character(lon))
                }
                # Last Monday in August replaces first Monday in August
                lon <- timeDate(.last.of.nday(y, 8, 31, 1), zone = "London", FinCenter = "Europe/London")
                holidays <- c(holidays, as.character(lon))
            }
            
            # Not entirely sure when Mon/Tue began to be given as holiday when Christmas/Boxing Day fell on
            # Saturday/Sun. I'm assuming this was after the 1971 Banking and Financial Dealings Act which 
            # established the new holiday schedule.
            if (y < 1970) {
                # Christmas and Boxing Day
                holidays <- c(holidays, as.character(ChristmasDay(y)), as.character(BoxingDay(y)))
            } else {
                posix1 <- as.POSIXlt(ChristmasDay(y))
                # If Christmas on Saturday or Sunday, then the following Monday and Tuesday are holidays
                if (posix1$wday == 0) { # Christmas Sunday
                    holidays <- c(holidays, as.character(ChristmasDay(y) + (1 : 2) * 86400))
                } else if (posix1$wday == 6) { #Christmas Saturday
                    holidays <- c(holidays, as.character(ChristmasDay(y) + (2 : 3) * 86400)) 
                } else if (posix1$wday == 5) {# Christmas Friday
                    # the next Monday is a holiday
                    holidays <- c(holidays, as.character(ChristmasDay(y) + c(0, 3) * 86400))
                } else {
                    holidays <- c(holidays, as.character(ChristmasDay(y)), as.character(BoxingDay(y)))
                }  
            }
            
            if (y >= 1974) {
                # New Year's Day: if it falls on Sat/Sun, then is moved to following Monday
                posix1 <- as.POSIXlt(NewYearsDay(y))
                if (posix1$wday == 0 | posix1$wday == 6) {
                    lon <- timeDate(.on.or.after(y, 1, 1, 1), zone = "London", FinCenter = "Europe/London")    
                } else {
                    holidays <- c(holidays, as.character(posix1)) 
                }
            }
            if (y >= 1978) {
                # First Monday of May became a bank holiday
                if (y == 1995) {
                    # Was moved to May 8 to celebrate VE Day's 50th anniversary
                    dts <- paste(y, "-05-08", sep = "")
                    holidays <- c(holidays, dts)
                } else {
                    lon <- timeDate(.on.or.after(y, 5, 1, 1), zone = "London", FinCenter = "Europe/London")
                    holidays <- c(holidays, as.character(lon))
                }
            }
        }
    }
    holidays <- sort(holidays)
    ans <- timeDate(format(holidays), zone = "London", FinCenter = "Europe/London")
    posix1 <- as.POSIXlt(ans, tz = "GMT")
    ans[!(posix1$wday == 0 | posix1$wday == 6)] # Remove any Saturdays/Sundays
} 		 	   		  
	[[alternative HTML version deleted]]

