         (nth (1- month) '(31 28 31 30 31 30 31 31 30 31 30 31)))
     (error "Month out of range, MONTH=%S" month)))
 
+(defun ledger-schedule-encode-day-of-week ( day-string)
+	"return the numerical day of week corresponding to DAY-STRING"
+	(cond ((string= day-string "Su") 7)
+				((string= day-string "Mo") 1)
+				((string= day-string "Tu") 2)
+				((string= day-string "We") 3)
+				((string= day-string "Th") 4)
+				((string= day-string "Fr") 5)
+				((string= day-string "Sa") 6)))
 ;; Macros to handle date expressions
 
 (defun ledger-schedule-constrain-day-in-month (count day-of-week)

(defun ledger-schedule-constrain-day (year-desc month-desc day-desc)
	(cond ((string= day-desc "*")
				 t)
				((/= 0 (string-to-number day-desc))
				 `(memq (nth 3 (decode-time date)) ',(mapcar 'string-to-number (split-string day-desc ","))))
				(t
				 (error "Improperly specified day constraint: %s %s %s" year-desc month-desc day-desc))))

(defun ledger-schedule-parse-date-descriptor (descriptor)
  "Parse the date descriptor, return the evaluator"
  (ledger-schedule-compile-constraints descriptor))

(defun ledger-schedule-list-upcoming-xacts (candidate-items early horizon)
  "Search CANDIDATE-ITEMS for xacts that occur within the period today - EARLY  to today + HORIZON"

(defun ledger-schedule-constrain-every-count-day (day-of-week skip start-date)
  "Return a form that is true for every DAY skipping SKIP, starting on START.
For example every second Friday, regardless of month."
  (let ((start-day (nth 6 (decode-time start-date))))
    (if (eq start-day day-of-week)  ;; good, can proceed
        `(zerop (mod (- (time-to-days date) ,(time-to-days start-date)) ,(* skip 7)))
      (error "START-DATE day of week doesn't match DAY-OF-WEEK"))))

(defun ledger-schedule-constrain-date-range (month1 day1 month2 day2)
