开发者

Given a weekday and the day of the month it occurs, can I get its ordinal position in constant time?

Say I'm given a date, from which I can get its day of the month and day of the week. For example (in Javascript):

var d = new Date(1316038581772); // Wed Sep 14 2011 12:16:21 GMT-1000
var dayOfWeek = d.getDay(); // 3 - Wednesday
var dayOfMonth = d.getDate(); // 14 - Day of month

I'm looking for a value n such that this date is the nth day of the week in the month. In this case, I'm looking for n=2, for the 2nd Wednesday in September 2011.

The naive algorithm would be to find the first occurrence of that weekday in the month, take the difference in days, and divide by 7, but this isn't in constant time. For example, I would need to iterate over each day from the first day in September 7 times to reach the first Wednesday.

Is there a constant-time solution to this problem?

(For anyone interested, I'm trying to generate ordinal values for iCalendar recurrence rules; given a date, generate the monthly recurrence for the nth day of each month. The rule 开发者_如何转开发for this case would be something like

RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=WE;BYSETPOS=2

or

RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=2WE

)


Divide by 7 and round up.

The 14th is always the 2nd [weekday] of the month, the 15th is always the 3rd [weekday] of the month, etc.


Take the day of the month, add 6, and divide by 7, throwing away the remainder.


You need two functions- one to get the day info, the other for the nth.

Number.prototype.nth= function(){
    var n= Math.round(this), t= Math.abs(n%100), i= t%10;
    if(i<4 && (t<4 || t> 20)){
        switch(i){
            case 1:return n+'st';
            case 2:return n+'nd';
            case 3:return n+'rd';
        }
    }
    return n+'th';
}
Date.prototype.nthofMonth= function(){
    var today= this.getDate(),m=this.getMonth(),
    day= ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
    'Friday', 'Saturday'][this.getDay()],
    month= ['January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November', 'December'][m];
    return [(m+1)+'-'+today,'the ', (Math.ceil((today)/7)).nth(), day, 'of', month, 'in', this.getFullYear()].join(' ');
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜