Billing Period
May 18, 2018
We provide a function period
that takes a year, month and day and returns the billing period within the requested year:
(define (period year month day) (define (first-of-month? julian) (call-with-values (lambda () (gregorian julian)) (lambda (year month day) (= day 1)))) (do ((j (julian year 1 1) (+ j 1)) (p 0 (+ p (if (or (= (modulo j 7) 5) (first-of-month? j)) 1 0)))) ((< (julian year month day) j) p)))
Here’s an example:
> (period 2018 5 18)
24
The 24 days on which billing periods start are:
1/1, 1/6, 1/13, 1/20, 1/27
2/1, 2/3, 2/10, 2/17, 2/24
3/1, 3/3, 3/10, 3/17, 3/24, 3/31
4/1, 4/7, 4/14, 4/21, 4/28
5/1, 5/5, 5/12
It is easy to see that the program is correct; it examines each day from January 1st to the requested date and increments a counter if the day is the 1st of a month or a Saturday. There’s another algorithm that divides the number of days from January 1st to the requested date by 7, then adjusts for Saturdays at the ends of the range, but after several tries I was unable to get it working, so I gave up. The moral of the story is that you want to write clear, simple code.
You can run the program at https://ideone.com/UhtqXu.
Mumps/Cache version
What ?
Mumps/Cache version, with comments and expanded commands, etc
Here’s a solution in C.
Example:
In Ruby.
Output:
2018-01-01 -> 1
2018-01-03 -> 1
2018-01-06 -> 2
2018-01-10 -> 2
2018-01-26 -> 4
2018-02-01 -> 6
2018-05-18 -> 24