|
xquery version "3.1"; |
|
|
|
(: A more generalized approach to finding the 2nd Tuesdays in a year :) |
|
|
|
import module namespace functx = "http://www.functx.com"; |
|
|
|
(:~ List the dates of any day in the week in a week in a month (e.g., 5th Sundays) between two dates |
|
: |
|
: @param $start-date The start date (inclusive) |
|
: @param $end-date The end date (inclusive) |
|
: @param $week-of-month The nth week of the month, as 1-5 |
|
: @param $day-of-week The day of the week, as 0-6 (0 = Sunday) |
|
: @return Dates meeting criteria |
|
: |
|
: @see http://www.xqueryfunctions.com/xq/functx_days-in-month.html |
|
: @see http://www.xqueryfunctions.com/xq/functx_date.html |
|
: @see http://www.xqueryfunctions.com/xq/functx_day-of-week.html |
|
:) |
|
declare function local:nth-weekdays( |
|
$start-date as xs:date, |
|
$end-date as xs:date, |
|
$week-of-month as xs:integer, |
|
$day-of-week as xs:integer |
|
) as xs:date* { |
|
let $start-year := year-from-date($start-date) |
|
let $end-year := year-from-date($end-date) |
|
let $start-month := month-from-date($start-date) |
|
let $end-month := month-from-date($end-date) |
|
for $year in $start-year to $end-year |
|
let $months := |
|
if ($year eq $start-year and $year eq $end-year) then |
|
$start-month to $end-month |
|
else if ($year eq $start-year) then |
|
$start-month to 12 |
|
else if ($year eq $end-year) then |
|
1 to $end-month |
|
else |
|
1 to 12 |
|
for $month in $months |
|
let $days-in-month := functx:days-in-month(functx:date($year, $month, 1)) |
|
let $day-offset := 7 * ($week-of-month - 1) + 1 |
|
for $day in ($day-offset to ($day-offset + 6))[. le $days-in-month] |
|
let $date := functx:date($year, $month, $day) |
|
where $date ge $start-date and $date le $end-date |
|
return |
|
if (functx:day-of-week($date) eq $day-of-week) then |
|
$date |
|
else |
|
() |
|
}; |
|
|
|
(:~ List the dates of all 2nd Tuesdays in a year |
|
: |
|
: @param $year A year |
|
: @returns Dates |
|
:) |
|
declare function local:second-tuesdays($year as xs:string) { |
|
let $start-date := xs:date($year || "-01-01") |
|
let $end-date := xs:date($year || "-12-31") |
|
let $week-of-month := 2 |
|
let $day-of-week := 2 |
|
return |
|
local:nth-weekdays($start-date, $end-date, $week-of-month, $day-of-week) |
|
}; |
|
|
|
local:second-tuesdays("2021") |