Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easy way of specifying holidays? #27

Open
srfoster opened this issue Nov 7, 2018 · 4 comments
Open

Easy way of specifying holidays? #27

srfoster opened this issue Nov 7, 2018 · 4 comments
Labels
enhancement maybe for successor Possibly defer to gregor's successor library

Comments

@srfoster
Copy link

srfoster commented Nov 7, 2018

For example, is there some way I could do something analogous to the following?

(define thanksgiving (fourth (thursdays november)))

@97jaz
Copy link
Owner

97jaz commented Nov 8, 2018

I have something along these lines in the unreleased sequel to gregor, though it differs from your example in one important respect: "the fourth Thursday of November" is a fine abstract description of Thanksgiving, though to get a date out of it, you'd need to apply it to a year. Whereas the code I have only works with concrete dates. (Your version is similar to the existing concept of a "date period," where you can specify a "period of N years," which has no concrete duration until you add it to an actual date.)

Anyhow, this is what I have right now:

(define (last-day-of-month year month)
  (date year month (days-in-month year month)))

(define (nth-wday-in-month year month wday n)
  (cond [(>= n 0)
         (define first-of-month (date year month))
         (define first-of-month-wday (date->wday first-of-month))
         (define diff (mod (- wday first-of-month-wday) 7))
         (date-add-days first-of-month (+ diff (* 7 (sub1 n))))]
        [else
         (define last (last-day-of-month year month))
         (define last-wday (date->wday last))
         (define diff
           (let ([d1 (- wday last-wday)])
             (cond [(zero? d1) 0]
                   [(> d1 0) (- d1 7)]
                   [else d1])))
         (date-add-days last (- diff (* 7 (sub1 (- n)))))]))

nth-wday-in-month has a bit of a strange interface. It's 1-indexed, so (nth-wday-in-month 2018 11 4 4) would give you the date of the fourth Thursday in November 2018. If you give it a negative value for n, it counts backwards from the last occurrence of wday in the month. (The odd case of n=0 gives you the last occurrence of wday in the month previous. Like I said, strange.)

I'm curious if you have a particular mode of usage in mind for your more abstract interface.

@97jaz
Copy link
Owner

97jaz commented Nov 8, 2018

BTW, that definition depends on some other things, like mod, which is defined in a private math module (it exists in gregor as well as in the newer, unreleased library).

@97jaz
Copy link
Owner

97jaz commented Nov 8, 2018

Err... though the negative case for n appears to be wrong, which is troubling:

> (nth-wday-in-month 2018 11 4 -1)
#<date 2018-12-01>

Update: fixed now:

> (nth-wday-in-month 2018 11 4 -1)
#<date 2018-11-29>

@97jaz
Copy link
Owner

97jaz commented Nov 8, 2018

Yeah, that was a silly typo in the cond. I've updated the source above.

@97jaz 97jaz added enhancement maybe for successor Possibly defer to gregor's successor library labels Nov 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement maybe for successor Possibly defer to gregor's successor library
Projects
None yet
Development

No branches or pull requests

2 participants