443,768 Members | 2,004 Online
Need help? Post your question and get tips & solutions from a community of 443,768 IT Pros & Developers. It's quick & easy.

# Find day of week from month and year

 P: n/a Hi Gurus, I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. I have tried a few tricks with the functions provided by the built-in module time, but the problem was that the 9 element tuple need to be populated correctly. Can anyone help me out on this one? Thanks a bunch, Laguna Requirements: d0 = expiration(9, 2005) # d0 would be 16 d1 = expiration(6, 2003) # d1 would be 20 d2 = expiration(2, 2006) # d2 would be 17 Sep 2 '05 #1
20 Replies

 P: n/a "Laguna" writes: I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. I have tried a few tricks with the functions provided by the built-in module time, but the problem was that the 9 element tuple need to be populated correctly. Can anyone help me out on this one? It's probably simplest to use the calendar module: http://docs.python.org/lib/module-calendar.html see the weekday function. d0 = expiration(9, 2005) # d0 would be 16 d1 = expiration(6, 2003) # d1 would be 20 d2 = expiration(2, 2006) # d2 would be 17 # not completely tested import calendar def expiration(month, year): w1 = calendar.weekday(year, month, 1) # weekday of 1st of month f1d = 1 + (4-w1) % 7 # date of 1st friday return f1d + 14 # date of 3rd friday Sep 2 '05 #2

 P: n/a Laguna wrote: Hi Gurus, I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. I have tried a few tricks with the functions provided by the built-in module time, but the problem was that the 9 element tuple need to be populated correctly. Can anyone help me out on this one? mx.DateTime provides a RelativeDateTime constructor that handles things like this. http://www.egenix.com/files/python/mxDateTime.html -- Robert Kern rk***@ucsd.edu "In the fields of hell where the grass grows high Are the graves of dreams allowed to die." -- Richard Harter Sep 2 '05 #3

 P: n/a In article <11**********************@g47g2000cwa.googlegroups .com>, "Laguna" wrote: I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. I have tried a few tricks with the functions provided by the built-in module time, but the problem was that the 9 element tuple need to be populated correctly. Can anyone help me out on this one? .... Requirements: d0 = expiration(9, 2005) # d0 would be 16 d1 = expiration(6, 2003) # d1 would be 20 d2 = expiration(2, 2006) # d2 would be 17 What do you mean by, "the 9 element tuple need to be populated correctly"? Do you need someone to tell you what values it needs? What happens if you use (2005, 9, 1, 0, 0, 0, 0, 0, 0), for example? If you make this tuple with localtime or gmtime, do you know what the 7th (tm[6]) element of the tuple is? What tricks did you try, exactly? Donn Cave, do**@u.washington.edu Sep 2 '05 #4

 P: n/a > What do you mean by, "the 9 element tuple need to be populated correctly"? Do you need someone to tell you what values it needs? What happens if you use (2005, 9, 1, 0, 0, 0, 0, 0, 0), for example? If you make this tuple with localtime or gmtime, do you know what the 7th (tm[6]) element of the tuple is? What tricks did you try, exactly? Donn Cave, do**@u.washington.edu Thanks for pointing out. tm[6] = weekday, and tm[7] = Julian data, but I wouldn't know these values when my input values are month and year. I will try out the more constructive suggestions from Paul and Robert. Following is what I have tried. As you can tell, the results are wrong! import time time.asctime((2003, 9, 1, 0, 0, 0, 0, 0, 0)) 'Mon Sep 01 00:00:00 2003' time.asctime((2003, 8, 1, 0, 0, 0, 0, 0, 0)) 'Mon Aug 01 00:00:00 2003' time.asctime((2003, 7, 1, 0, 0, 0, 0, 0, 0)) 'Mon Jul 01 00:00:00 2003' Sep 2 '05 #5

 P: n/a Paul, Thanks for the suggestion on calendar module. Here is my solution and it works: def expiration(year, month): weekday = calendar.weekday(year, month, 1) table = [19, 18, 17, 16, 15, 21, 20] return table[weekday] Cheers, Laguna Sep 2 '05 #6

 P: n/a On Fri, 2005-09-02 at 16:46, Laguna wrote: Paul, Thanks for the suggestion on calendar module. Here is my solution and it works: def expiration(year, month): weekday = calendar.weekday(year, month, 1) table = [19, 18, 17, 16, 15, 21, 20] return table[weekday] Cheers, Laguna This, of course, can be "optimized" into def expiration(year, month): return [19,18,17,16,15,21,20][calendar.weekday(year,month,1)] ;) -Carsten Sep 2 '05 #7

 P: n/a Thanks for the "hint" :) I may use your solution if this becomes my bottleneck! I try to get away from Perl-ish syntax though. Best, L Sep 2 '05 #8

 P: n/a In article <11**********************@g49g2000cwa.googlegroups .com>, "Laguna" wrote: What do you mean by, "the 9 element tuple need to be populated correctly"? Do you need someone to tell you what values it needs? What happens if you use (2005, 9, 1, 0, 0, 0, 0, 0, 0), for example? If you make this tuple with localtime or gmtime, do you know what the 7th (tm[6]) element of the tuple is? What tricks did you try, exactly? Donn Cave, do**@u.washington.edu Thanks for pointing out. tm[6] = weekday, and tm[7] = Julian data, but I wouldn't know these values when my input values are month and year. I will try out the more constructive suggestions from Paul and Robert. Following is what I have tried. As you can tell, the results are wrong! import time time.asctime((2003, 9, 1, 0, 0, 0, 0, 0, 0)) 'Mon Sep 01 00:00:00 2003' time.asctime((2003, 8, 1, 0, 0, 0, 0, 0, 0)) 'Mon Aug 01 00:00:00 2003' time.asctime((2003, 7, 1, 0, 0, 0, 0, 0, 0)) 'Mon Jul 01 00:00:00 2003' Well, sure, that tm value will certainly not be the 3rd Friday, but it does correctly represent the first day of the month. With localtime() you can find out the day of the week, on the first day of the month. When you know that, the 3rd Friday is simple arithmetic. Since other followups have already spoon-fed you a solution (assuming it works, haven't tried), here's an example of what I mean - import time for m in range(1, 13): c1 = time.mktime((2005, m, 1, 0, 0, 0, 0, 0, 0)) d1 = time.localtime(c1)[6] if d1 > 4: f3 = 26 - d1 else: f3 = 19 - d1 # f3 = 19 + (d1 // 5) * 7 - d1 c3 = time.mktime((2005, m, f3, 0, 0, 0, 0, 0, 0)) print time.ctime(c3) I don't know if you intend to go on to do much more programming after this, but that's who I normally assume we're talking to here, programmers. No one knows everything and misses nothing, certainly not me, but it's nice when people come to comp.lang.python and can account for at least the beginning of some analysis of their problem. When that's missing, it's hard to know what's really constructive. Donn Cave, do**@u.washington.edu Sep 2 '05 #9

 P: n/a Hey Donn, I don't mean to offend anyone here. I was just saying that the other solution is better suited for my problem. I truly appreciate your analysis and suggestions. BTW, I am not a programmer :( and I like the simplest solution whenever possible. Cheers, L Sep 2 '05 #10

 P: n/a Carsten Haese wrote: On Fri, 2005-09-02 at 16:46, Laguna wrote:def expiration(year, month): weekday = calendar.weekday(year, month, 1) table = [19, 18, 17, 16, 15, 21, 20] return table[weekday] This, of course, can be "optimized" into def expiration(year, month): return [19,18,17,16,15,21,20][calendar.weekday(year,month,1)] ;) True, but do you find that more readable? If I saw that in code I was maintaining I would likely rewrite it, probably to look a lot like the first one (though likely with a more descriptive name than "table"... maybe expirationTable?). (And, if I were "optimizing", I would of course dispense with the dynamic creation of the static table upon every execution of expiration(), and move it outside the function.) -Peter Sep 3 '05 #11

 P: n/a Peter Hansen writes: (And, if I were "optimizing", I would of course dispense with the dynamic creation of the static table upon every execution of expiration(), and move it outside the function.) Replacing it with a tuple might be enough for that. Sep 3 '05 #12

 P: n/a Peter Hansen wrote: Carsten Haese wrote: On Fri, 2005-09-02 at 16:46, Laguna wrote: def expiration(year, month): weekday = calendar.weekday(year, month, 1) table = [19, 18, 17, 16, 15, 21, 20] return table[weekday] This, of course, can be "optimized" into def expiration(year, month): return [19,18,17,16,15,21,20][calendar.weekday(year,month,1)] ;) True, but do you find that more readable? If I saw that in code I was maintaining I would likely rewrite it, probably to look a lot like the first one (though likely with a more descriptive name than "table"... maybe expirationTable?). (And, if I were "optimizing", I would of course dispense with the dynamic creation of the static table upon every execution of expiration(), and move it outside the function.) -Peter An alternative: def expiration(year, month): return 21 - (calendar.weekday(year,month,1) + 2) % 7 Sep 3 '05 #13

 P: n/a Donn, You didn't look closely enough at those results. The OP's point was that he did not know how to set all the tuple values correctly. Here's a clearer example, I think: import time print time.asctime((2005,9,1,0,0,0,0,0,0)) print time.asctime((2005,9,1,0,0,0,1,0,0)) print time.asctime((2005,9,1,0,0,0,2,0,0)) print time.asctime((2005,9,1,0,0,0,3,0,0)) Prints: Mon Sep 01 00:00:00 2005 Tue Sep 01 00:00:00 2005 Wed Sep 01 00:00:00 2005 Thu Sep 01 00:00:00 2005 No matter what time zone you're in, Sep 1, 2005 can't be all those days of the week! :) Your code works because you use mktime, which appears to ignore the dayOfWeek element of the input tuple, as shown by the following: print time.asctime(time.gmtime(time.mktime((2005,9,1,0,0 ,0,0,0,0)))) print time.asctime(time.gmtime(time.mktime((2005,9,1,0,0 ,0,1,0,0)))) print time.asctime(time.gmtime(time.mktime((2005,9,1,0,0 ,0,2,0,0)))) print time.asctime(time.gmtime(time.mktime((2005,9,1,0,0 ,0,3,0,0)))) Prints: Thu Sep 01 06:00:00 2005 Thu Sep 01 06:00:00 2005 Thu Sep 01 06:00:00 2005 Thu Sep 01 06:00:00 2005 -- Paul Sep 3 '05 #14

 P: n/a Paul Rubin wrote: Peter Hansen writes:(And, if I were "optimizing", I would of course dispense with thedynamic creation of the static table upon every execution ofexpiration(), and move it outside the function.) Replacing it with a tuple might be enough for that. You're right, and in fact that would actually be even faster since then it's a LOAD_CONST instead of a LOAD_GLOBAL. -Peter Sep 3 '05 #15

 P: n/a On Fri, 02 Sep 2005 20:53:44 -0400, Peter Hansen wrote: Carsten Haese wrote: On Fri, 2005-09-02 at 16:46, Laguna wrote:def expiration(year, month): weekday = calendar.weekday(year, month, 1) table = [19, 18, 17, 16, 15, 21, 20] return table[weekday] .... True, but do you find that more readable? If I saw that in code I was maintaining I would likely rewrite it, probably to look a lot like the first one (though likely with a more descriptive name than "table"... maybe expirationTable?). That doesn't explain anything, IMHO. What 'table' really is is a list of day-of-month candidates for the third Friday. For some pieces of code, I find that it's better to document what it /does/ than to try to document /how/ it does it. And maybe add a bunch of unit tests to /demonstrate/ that it seems to work. The next programmer can then choose to either (a) understand the code or (b) rip it out and replace it. I would leave the body alone, but rename the function 'third_friday_of_month', and do 'expiration = third_friday_of_month'. /Jorgen -- // Jorgen Grahn R'lyeh wgah'nagl fhtagn! Sep 3 '05 #16

 P: n/a Laguna wrote: Hi Gurus, I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. I have tried a few tricks with the functions provided by the built-in module time, but the problem was that the 9 element tuple need to be populated correctly. Can anyone help me out on this one? Thanks a bunch, Laguna Requirements: d0 = expiration(9, 2005) # d0 would be 16 d1 = expiration(6, 2003) # d1 would be 20 d2 = expiration(2, 2006) # d2 would be 17 Sep 14 '05 #17

 P: n/a Laguna wrote: Hi Gurus, I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. I have tried a few tricks with the functions provided by the built-in module time, but the problem was that the 9 element tuple need to be populated correctly. Can anyone help me out on this one? Thanks a bunch, Laguna Requirements: d0 = expiration(9, 2005) # d0 would be 16 d1 = expiration(6, 2003) # d1 would be 20 d2 = expiration(2, 2006) # d2 would be 17 import calendar [y[4] for y in calendar.monthcalendar(2005, 9) if y[4]!=0][2] 16 [y[4] for y in calendar.monthcalendar(2003, 6) if y[4]!=0][2] 20 [y[4] for y in calendar.monthcalendar(2006, 2) if y[4]!=0][2] 17 Sep 14 '05 #18

 P: n/a >>> import calendar [y[4] for y in calendar.monthcalendar(2005, 9) if y[4]!=0][2] 16 [y[4] for y in calendar.monthcalendar(2003, 6) if y[4]!=0][2] 20 [y[4] for y in calendar.monthcalendar(2006, 2) if y[4]!=0][2] 17 Sep 14 '05 #19

 P: n/a Laguna wrote: I want to find the expiration date of stock options (3rd Friday of the month) for an any give month and year. From year and month (and day=1) get the day of the week (n in [0,6]) of the first of the month using some version of the the standard formula (see below) and look up the third friday date in a precalculated 7-element list, or, with n=0 on Saturday, 3rd Friday is 21-n Here is a translation of the guts of a 30-year-old Basic program: def friday3(m,y): # ints if m <= 2: m += 12 y -= 1 d = 1 n = d + 2*m + int(.6*(m+1)) + y + y//4 - y//100 + y//400 + 2 n = int((n/7.0- n//7)*7.0 + .5) # n=0 is Saturday, making 3rd Friday the 21st. return 21 - n Requirements: d0 = expiration(9, 2005) # d0 would be 16 d1 = expiration(6, 2003) # d1 would be 20 d2 = expiration(2, 2006) # d2 would be 17 for m,y in ((9,2005), (6,2003), (2,2006)): print friday3(m,y) .... 16 20 17 Terry J. Reedy Sep 14 '05 #20

 P: n/a Terry Reedy wrote:Laguna wrote:I want to find the expiration date of stock options (3rd Friday of themonth) for an any give month and year.From year and month (and day=1) get the day of the week (n in [0,6]) of the first of the month using some version of the the standard formula (see below) and look up the third friday date in a precalculated 7-element list, or, with n=0 on Saturday, 3rd Friday is 21-n Here is a translation of the guts of a 30-year-old Basic program: def friday3(m,y): # ints if m <= 2: m += 12 y -= 1 d = 1 n = d + 2*m + int(.6*(m+1)) + y + y//4 - y//100 + y//400 + 2 Some simplification is possible: [2*m + int(.6*(m+1)) for m in range(15)] [0, 3, 5, 8, 11, 13, 16, 18, 21, 24, 26, 29, 31, 34, 37] [(13*m+3)//5 for m in range(15)] [0, 3, 5, 8, 11, 13, 16, 18, 21, 24, 26, 29, 31, 34, 37] n = int((n/7.0- n//7)*7.0 + .5) n %= 7 # n=0 is Saturday, making 3rd Friday the 21st. return 21 - nRequirements:d0 = expiration(9, 2005) # d0 would be 16d1 = expiration(6, 2003) # d1 would be 20d2 = expiration(2, 2006) # d2 would be 17for m,y in ((9,2005), (6,2003), (2,2006)): print friday3(m,y) ... 16 20 17 Terry J. Reedy Sep 15 '05 #21

### This discussion thread is closed

Replies have been disabled for this discussion.