Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Uk Bank Holiday XML Web Service?

Status
Not open for further replies.

BeckD

Programmer
Apr 16, 2002
53
0
0
GB
Hi
Does anyone know of anywhere that provides an xml file of uk bank holidays? I want to integrate bank holidays into a project and I'm trying to avoid having to keep a database/ file or anything manually up to date so I was hoping that an xml web service was available for this purpose - similarly to how xml news feeds work.

Anyone got any ideas?

Cheers,
Beck
 
I don't know of a web service that provides this information, but you should be able to calculate the dates for any given year rather than having to manually bash them in.

Here's a set of routines I wrote in Perl to sit behind one of my web sites, maybe you can pick some useful stuff from it:
Code:
@MONTHS = ('','January', 'February', 'March', 'April', 'May', 'June',  
           'July', 'August', 'September', 'October', 'November',
           'December');

@DAYS = ('','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday');

@DAYSINYEAR = (
[ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 ],
[ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 ]
);

@DAYSINMONTH = (
[ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
[ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
);

sub leap_year {
   my ($year) = @_;
   my $yy = int ($year/100);
   if ($year > 0) {
      return ((($year & 0x03) ==0) &&
             (( $yy * 100 != $year) ||
             (($yy & 0x03) == 0) ) ) ? 1 : 0;
   } else {
      return '';
   }
}

sub check_date_leap {
   my ($day, $month, $year) = @_;
   my $leap = leap_year($year);
   return (($year >= 1) &&
           ($month >= 1) && ($month <= 12) &&
           ($day >= 1) &&
           ($day <= $DAYSINMONTH[$leap][$month])) ? $leap : -1;
}

sub Year_to_Days {
   my ($year) = @_;
   my $days = 365 * $year;

   $days += ($year >>= 2);
   $year = int ($year / 25);
   $days -= $year;
   $days += ($year >>  2);
   return $days;
}

sub Date_to_Days {
   my ($day, $month, $year) = @_;
   my $leap = check_date_leap( $day, $month, $year );

   if ($leap >= 0) {
      return (Year_to_Days(--$year) +
             $DAYSINYEAR[$leap][$month] + $day );
   } else {
      return '';
   }
}

sub day_of_week {
   my ($day, $month, $year) = @_;
   my $n_days = Date_to_Days($day, $month, $year);
   if ($n_days > 0) {
      $n_days--;
      $n_days %= 7;
      $n_days++;
      return $n_days;
   } else {
      return '';
   }
}

sub split_date {
   local ($date) = $_[0];
   local ($day,$month,$year);

   if ($date) {
      $day = $date % 100;
      $month = (int ($date/100)) % 100;
      $year = int ($date/10000);
   } else {
      ($day,$month,$year) = ('','','');
   }

   return ($day,$month,$year);
}

sub join_date {
   local ($day,$month,$year) = @_;
   local ($date);

   if ($day > $DAYSINMONTH[leap_year($year)][$month] ) {
      $date = -1;
   } else { 
      $date = ($year * 10000) + ($month * 100) + $day;
   }
   return ($date);
}

sub easter_sunday
{
	my ($year) = @_;
	my ($month, $day);
    ################################################################
    #                                                              #
    #  Gauss'sche Regel (Gaussian Rule)                            #
    #  ================================                            #
    #                                                              #
    #  Quelle / Source:                                            #
    #                                                              #
    #  H. H. Voigt, "Abriss der Astronomie", Wissenschaftsverlag,  #
    #  Bibliographisches Institut, Seite 9.                        #
    #                                                              #
    ################################################################

    my ($a, $b, $c, $d, $e, $m, $n);

    if (($year <= 0) || ($year < 1583) || ($year > 2299)) {
       die "Easter_Sunday: Year out of range";
    }

    if    ($year < 1700) { $m = 22; $n = 2; }
    elsif ($year < 1800) { $m = 23; $n = 3; }
    elsif ($year < 1900) { $m = 23; $n = 4; }
    elsif ($year < 2100) { $m = 24; $n = 5; }
    elsif ($year < 2200) { $m = 24; $n = 6; }
    else                 { $m = 25; $n = 0; }

    $a = $year % 19;
    $b = $year % 4;
    $c = $year % 7;
    $d = (19 * $a + $m) % 30;
    $e = (2 * $b + 4 * $c + 6 * $d + $n) % 7;
    $day = 22 + $d + $e;
    $month = 3;
    if ($day > 31)
    {
        $day -= 31; # same as $day = $d + $e - 9; 
        $month++;
    }
    if (($day == 26) && ($month == 4))
	{
		$day = 19;
	}
    if (($day == 25) && ($month == 4) && 
        ($d == 28) && ($e == 6) && ($a > 10))
	{
		$day = 18;
	}
    return (&join_date($day, $month, $year));
}


#
# hash_holidays : Fills a hash with all holiday dates for the specified year
#
sub hash_holidays {
   local ($year) = $_[0];
   local (%holiday) = ();

   # New Year's Day
   local($testday) = &day_of_week (1,1,$year);

   if ($testday > 5) {
      $holiday{&join_date((9 - $testday),1,$year)} = 1;
   } else {
      $holiday{&join_date(1,1,$year)} = 1;
   }

   #
   # Calculate Easter to get Good Friday & Easter Monday
   #
   local ($easter) = &easter_sunday($year);

   $holiday{&prev_date(&prev_date($easter))} = 1;   # Good Friday
   $holiday{&next_date($easter)} = 1;               # Easter Monday

   #
   # Bank hols on first & last monday in May + last monday in August
   #

   $testday = &day_of_week (1,5,$year);
   if ($testday == 1) {
      $holiday{&join_date(1,5,$year)} = 1;
   } else {
      $holiday{&join_date((9 - $testday),5,$year)} = 1;
   }

   $testday = &day_of_week (31,8,$year);
   $holiday{&join_date((32 - $testday),8,$year)} = 1;

   #
   # ... unless it's 2002 (god bless you ma'am)
   #
   if ($year == 2002) {
      $holiday{&join_date(3,6,2002)} = 1;
      $holiday{&join_date(4,6,2002)} = 1;
   } else {
      $testday = &day_of_week (31,5,$year);
      $holiday{&join_date((32 - $testday),5,$year)} = 1;
   }

   #
   # Christmas Day & Boxing Day, unless they fall on a weekend
   #
   $testday = &day_of_week (25,12,$year);
   if ($testday > 5) {
      $holiday{&join_date(27,12,$year)} = 1;
      $holiday{&join_date(28,12,$year)} = 1;
   } elsif ($testday == 5) {
      $holiday{&join_date(25,12,$year)} = 1;
      $holiday{&join_date(28,12,$year)} = 1;
   } else {
      $holiday{&join_date(25,12,$year)} = 1;
      $holiday{&join_date(26,12,$year)} = 1;
   }

   return (%holiday);
}

1;
As you see, I've hard-coded a check for the special bank holiday we got in 2002 for the Golden Jubilee. You'd have to make similar manual adjustments for future one-off holidays.

-- Chris Hunt
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top