{{ message }}

Instantly share code, notes, and snippets.

# joewiz/Second Tuesdays.md

Last active Jun 21, 2021
Second Tuesdays of the year, with XQuery

Hi, anyone have function for calculate all second Tuesdays for year?

(That is, Patch Tuesdays.)

Below are two approaches—one that solves the problem directly (finding only 2nd Tuesdays) and one more generally (finding any combination of week of the month and day of the week, e.g., 5th Sundays).

 xquery version "3.1"; (: A basic approach to finding the 2nd Tuesdays in a year :) import module namespace functx = "http://www.functx.com"; (:~ List the dates of all 2nd Tuesdays in a year : : @param \$year A year : @return Dates : : @see http://www.xqueryfunctions.com/xq/functx_date.html : @see http://www.xqueryfunctions.com/xq/functx_day-of-week.html :) declare function local:second-tuesdays(\$year as xs:gYear) as xs:date+ { for \$month in 1 to 12 for \$day in 8 to 14 let \$date := functx:date(\$year, \$month, \$day) return if (functx:day-of-week(\$date) eq 0) then \$date else () }; local:second-tuesdays(2021)
 ( xs:date("2021-01-12"), xs:date("2021-02-09"), xs:date("2021-03-09"), xs:date("2021-04-13"), xs:date("2021-05-11"), xs:date("2021-06-08"), xs:date("2021-07-13"), xs:date("2021-08-10"), xs:date("2021-09-14"), xs:date("2021-10-12"), xs:date("2021-11-09"), xs:date("2021-12-14") )
 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:integer) { 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)
 ( xs:date("2021-01-12"), xs:date("2021-02-09"), xs:date("2021-03-09"), xs:date("2021-04-13"), xs:date("2021-05-11"), xs:date("2021-06-08"), xs:date("2021-07-13"), xs:date("2021-08-10"), xs:date("2021-09-14"), xs:date("2021-10-12"), xs:date("2021-11-09"), xs:date("2021-12-14") )