Give the source code of a function that takes in a DateTime, and calculates whether the given day is the 3rd Friday of the month. There is more than one way to do this, but elegance is always preferred. This is useful for calculating whether the Friday is options expiration Friday or not. Programming language is up to you, but preferably C or Java or Basic. nitro
Third Friday is not too hard, but you have to deal with Good Friday holidays sometimes. I just put all the Exp dates in a structure and find them when needed. Brute force and decidedly Not elegant. Works fine for me tho. Here's a little more elegant exp finder in WealthScript (mostly Pascal) you can convert to C. (not my code) Code: function ExpirationDate( Year, Month : integer ) : integer; begin var G_Date, G_Month, G_Year, G_Day : integer; var n, y, m, d, w : integer; function _jnbr( y, m, d : integer ) : integer; begin var a, s, j1, jd : float; jd := -1 * Int( 7 * ( Int( ( m + 9 ) / 12 ) + y ) / 4 ); s := integer( ( ( m - 9 ) < 0 ) or 1 ); a := Abs( m - 9 ); j1 := Int( y + s * Int( a / 7 ) ); j1 := -1 * Int( ( Int( j1 / 100 ) + 1 ) * 3 / 4 ); jd := jd + Int( 275 * m / 9 ) + d + j1; jd := jd + 1721029 + 367 * y; Result := Int( jd ); end; procedure _jdate( n : Integer ); begin var d, t, w, x, y, z : float; G_Date := 0; G_Month := 0; G_Year := 0; G_Day := -1; if ( n > 0 ) then begin x := n + 68569; y := Trunc( 4 * x/146097 ); x := x-Trunc( ( 146097 * y + 3 )/4 ); z := Trunc( 4000 * ( x + 1 )/1461001 ); x := x-Trunc( 1461 * z/4 ) + 31; w := Trunc( 80 * x/2447 ); t := x-Trunc( 2447 * w/80 ); x := Trunc( w/11 ); w := w + 2 - 12 * x; z := 100 * ( y - 49 )+ z + x; d := n + 0.5; G_Date := Int( t ); G_Month := Int( w ); G_Year := Int( z ); G_Day := 1 + Trunc( ( d/7 - Trunc( d/7 ) )* 7 + 0.000000000317 ); end; end; function GoodFri( y : integer ) : integer; begin var r, n, p : integer; var y1, a, b1, b, m1, m, q1, q, w1, w : float; n := y - 1900; y1 := n/19; a := Trunc( ( y1 - Trunc( y1 ) ) * 19+0.001 ); b1 := ( 7*a+1 )/19; b := Trunc( b1 ); m1 := ( 11 * a + 4 - b )/29; m := Trunc( ( m1 - Trunc( m1 ) ) * 29 + 0.001 ); q1 := n/4; q := Trunc( q1 ); w1 := ( n + q + 31 - m )/7; w := Trunc( ( w1 - trunc( w1 ) ) * 7 + 0.001 ); r := Int( 25 - m - w ); p := Int( r ); if ( r <= 0 ) then p := 31 + r; n := 4; if ( r <= 0 ) then n := 3; n := n - 1; result := _jnbr( y, n + 1, p - 2 ); end; for d := 15 to 21 do begin n := _jnbr( Year, Month, d ); _jdate( n ); d := G_Date; w := G_Day; if ( d >= 15 ) and ( d <= 21 ) and ( w = 5 ) then begin if n = GoodFri( Year ) then d := d - 1; Result := Year*10000 + Month*100 + d; Exit; end; end; end;
The following lines of VB code return the date of the third Friday in the month. If Weekday(DateSerial(Year(Now), Month(Now), 1)) = 7 Then Debug.Print DateAdd("d", 14 + 5, DateSerial(Year(Now), Month(Now), 1)) Else Debug.Print DateAdd("d", 14 + (6 - Weekday(DateSerial(Year(Now), Month(Now), 1))), DateSerial(Year(Now), Month(Now), 1)) End If The input is Now, which is today. You could compare the answer to Now and if the difference is zero, then today would be the third Friday in the month. I have not tested this extensively - but it certainly works for the current month.
Code: public class ThirdFriday { public boolean isOptionsFriday(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY && cal.get(Calendar.WEEK_OF_MONTH) == 3; } }
Look at a calendar for 2007. June 2007 shows you that the earliest possible date of a 3rd Friday, is the 15th of the month. December 2007 shows you that the latest possible date of a 3rd Friday, is the 21st of the month. So the test is (DayOfWeek == FRIDAY) AND (15 <= DayOfMonth <= 21). Simple and straightforward. Some people wish to CALCULATE the date of the 3rd Friday ratehr than merely testing whether a given day is, or is not, a 3rd Friday. TO do this simply, just write seven straightforward IF statements, viz, IF(the first of the month falls on a Saturday) THEN date_of_3rd_Friday = 21; IF(the first of the month falls on a Sunday) THEN date_of_3rd_Friday = 20; IF(the first of the month falls on a Monday) THEN date_of_3rd_Friday = 19; etc.
All excellent responses. This is my favorite, if it only worked in C# There is no WEEKOFMONTH parameter AFAIK. nitro
First, to readers that don't know, in VB the first day of the week is Sunday = 7, Monday = 1, Tuesday = 2, etc. The first part of the if clearly works. If the first day of the week is Sunday = 7, then add 19 days + 1 day, and you get the third Friday which would always be the 20th. That always works. The second part of the if is more complex. If the first of the month is any other day than Sunday, add 1 day to 14 + (6 - DayOfWeekOfFirstDayOfMonth), and that in theory is the third Friday. Doesn't works this month, Feb 2007: 14 + (6 - 4) + 1 = 17th (Unless Thursday is the 5th day in VB?) Interestingly enough, you can turn this calculation to get the weekofmonth using a little modular arithmetic once you get it working... nitro