Calculates the datetime of the occurrence from the year
(self, year)
| 587 | |
| 588 | # TODO: These are not actually epoch dates as they are expressed in local time |
| 589 | def year_to_epoch(self, year): |
| 590 | """Calculates the datetime of the occurrence from the year""" |
| 591 | # We know year and month, we need to convert w, d into day of month |
| 592 | # |
| 593 | # Week 1 is the first week in which day `d` (where 0 = Sunday) appears. |
| 594 | # Week 5 represents the last occurrence of day `d`, so we need to know |
| 595 | # the range of the month. |
| 596 | first_day, days_in_month = calendar.monthrange(year, self.m) |
| 597 | |
| 598 | # This equation seems magical, so I'll break it down: |
| 599 | # 1. calendar says 0 = Monday, POSIX says 0 = Sunday |
| 600 | # so we need first_day + 1 to get 1 = Monday -> 7 = Sunday, |
| 601 | # which is still equivalent because this math is mod 7 |
| 602 | # 2. Get first day - desired day mod 7: -1 % 7 = 6, so we don't need |
| 603 | # to do anything to adjust negative numbers. |
| 604 | # 3. Add 1 because month days are a 1-based index. |
| 605 | month_day = (self.d - (first_day + 1)) % 7 + 1 |
| 606 | |
| 607 | # Now use a 0-based index version of `w` to calculate the w-th |
| 608 | # occurrence of `d` |
| 609 | month_day += (self.w - 1) * 7 |
| 610 | |
| 611 | # month_day will only be > days_in_month if w was 5, and `w` means |
| 612 | # "last occurrence of `d`", so now we just check if we over-shot the |
| 613 | # end of the month and if so knock off 1 week. |
| 614 | if month_day > days_in_month: |
| 615 | month_day -= 7 |
| 616 | |
| 617 | ordinal = self._ymd2ord(year, self.m, month_day) |
| 618 | epoch = ordinal * 86400 |
| 619 | epoch += self.hour * 3600 + self.minute * 60 + self.second |
| 620 | return epoch |
| 621 | |
| 622 | |
| 623 | def _parse_tz_str(tz_str): |