|
75 | 75 | "daysOfMonth": "date",
|
76 | 76 | "daysOfWeek": "day",
|
77 | 77 | "weeksOfMonth": "monthWeek",
|
| 78 | + "weeksOfMonthByDay": "monthWeekByDay", |
78 | 79 | "weeksOfYear": "weeks",
|
79 | 80 | "monthsOfYear": "months"
|
80 | 81 | };
|
81 | 82 |
|
82 | 83 | // Dictionary of ranges based on measures
|
83 | 84 | var ranges = {
|
84 |
| - "daysOfMonth" : { low: 1, high: 31 }, |
85 |
| - "daysOfWeek" : { low: 0, high: 6 }, |
86 |
| - "weeksOfMonth" : { low: 0, high: 4 }, |
87 |
| - "weeksOfYear" : { low: 0, high: 52 }, |
88 |
| - "monthsOfYear" : { low: 0, high: 11 } |
| 85 | + "daysOfMonth" : { low: 1, high: 31 }, |
| 86 | + "daysOfWeek" : { low: 0, high: 6 }, |
| 87 | + "weeksOfMonth" : { low: 0, high: 4 }, |
| 88 | + "weeksOfMonthByDay" : { low: 0, high: 4 }, |
| 89 | + "weeksOfYear" : { low: 0, high: 52 }, |
| 90 | + "monthsOfYear" : { low: 0, high: 11 } |
89 | 91 | };
|
90 | 92 |
|
91 | 93 | // Private function for cehcking the range of calendar values
|
|
186 | 188 | "daysOfWeek": "calendar",
|
187 | 189 | "daysOfMonth": "calendar",
|
188 | 190 | "weeksOfMonth": "calendar",
|
| 191 | + "weeksOfMonthByDay": "calendar", |
189 | 192 | "weeksOfYear": "calendar",
|
190 | 193 | "monthsOfYear": "calendar"
|
191 | 194 | };
|
|
199 | 202 | "daysOfWeek": "dayOfWeek",
|
200 | 203 | "daysOfMonth": "dayOfMonth",
|
201 | 204 | "weeksOfMonth": "weekOfMonth",
|
| 205 | + "weeksOfMonthByDay": "weekOfMonthByDay", |
202 | 206 | "weeksOfYear": "weekOfYear",
|
203 | 207 | "monthsOfYear": "monthOfYear"
|
204 | 208 | };
|
|
245 | 249 | this.units = null;
|
246 | 250 | this.measure = null;
|
247 | 251 |
|
| 252 | + if (rule.measure === 'weeksOfMonthByDay' && !this.hasRule('daysOfWeek')) { |
| 253 | + throw Error("weeksOfMonthByDay must be combined with daysOfWeek"); |
| 254 | + } |
| 255 | + |
248 | 256 | // Remove existing rule based on measure
|
249 | 257 | for (var i = 0; i < this.rules.length; i++) {
|
250 | 258 | if (this.rules[i].measure === rule.measure) {
|
|
385 | 393 | case "weekOfMonth":
|
386 | 394 | return "weeksOfMonth";
|
387 | 395 |
|
| 396 | + case "weekOfMonthByDay": |
| 397 | + return "weeksOfMonthByDay"; |
| 398 | + |
388 | 399 | case "weekOfYear":
|
389 | 400 | return "weeksOfYear";
|
390 | 401 |
|
|
590 | 601 | }
|
591 | 602 | };
|
592 | 603 |
|
| 604 | + // Checks if a rule has been set on the chain |
| 605 | + Recur.prototype.hasRule = function(measure) { |
| 606 | + var i, len; |
| 607 | + for (i = 0, len = this.rules.length; i < len; i++) { |
| 608 | + if (this.rules[i].measure === pluralize(measure)) { |
| 609 | + return true; |
| 610 | + } |
| 611 | + } |
| 612 | + return false; |
| 613 | + }; |
| 614 | + |
593 | 615 | // Attempts to match a date to the rules
|
594 | 616 | Recur.prototype.matches = function(dateToMatch, ignoreStartEnd) {
|
595 | 617 | var date = moment(dateToMatch).dateOnly();
|
|
690 | 712 | return day0.diff(week0, "weeks");
|
691 | 713 | };
|
692 | 714 |
|
| 715 | + // Plugin for calculating the occurrence of the day of the week in the month. |
| 716 | + // Similar to `moment().monthWeek()`, the return value is zero-indexed. |
| 717 | + // A return value of 2 means the date is the 3rd occurence of that day |
| 718 | + // of the week in the month. |
| 719 | + moment.fn.monthWeekByDay = function(date) { |
| 720 | + var day, week0, day0, diff; |
| 721 | + |
| 722 | + // date obj |
| 723 | + day = this.clone(); |
| 724 | + |
| 725 | + // First day of the first week of the month |
| 726 | + week0 = this.clone().startOf("month").startOf("week"); |
| 727 | + |
| 728 | + // First day of week |
| 729 | + day0 = this.clone().startOf("week"); |
| 730 | + |
| 731 | + diff = day0.diff(week0, "weeks"); |
| 732 | + |
| 733 | + if (day.subtract(diff, "weeks").month() === this.clone().month()) { |
| 734 | + return diff; |
| 735 | + } |
| 736 | + |
| 737 | + return diff - 1; |
| 738 | + }; |
| 739 | + |
693 | 740 | // Plugin for removing all time information from a given date
|
694 | 741 | moment.fn.dateOnly = function() {
|
695 | 742 | if (this.tz && typeof(moment.tz) == 'function' ) {
|
|
0 commit comments