#lang scheme/base
(require "base.ss"
"depend.ss"
)
(define (build-date year month day (hour 0) (min 0) (sec 0) (nano 0) #:tz (tz 0))
(define (helper year month day)
(make-date nano sec min hour day month year tz))
(apply helper (normalize-year/month/day year month day)))
(define (date->date/tz d (tz #f))
(julian-day->date (date->julian-day d)
(if (not tz)
(date-zone-offset d)
tz)))
(define date-comp-type (make-parameter 'all))
(define (date-comp? comp?)
(define (helper d)
(date->julian-day (case (date-comp-type)
((day+time)
(make-date (date-nanosecond d)
(date-second d)
(date-minute d)
(date-hour d)
(date-day d)
(date-month d)
(date-year d)
0))
((day-only)
(make-date 0 0 0 0
(date-day d)
(date-month d)
(date-year d)
0))
(else d)
)))
(lambda (d1 d2 . dates)
(let ((dates (list* d1 d2 dates)))
(and (if (equal? (date-comp-type) 'date+tz)
(apply = (map date-zone-offset dates))
#t)
(apply comp? (map helper dates))))))
(define date=? (date-comp? =))
(define date>? (date-comp? >))
(define date<? (date-comp? <))
(define date>=? (date-comp? >=))
(define date<=? (date-comp? <=))
(define date!=? (date-comp? (compose not)))
(define (day-comp? comp?)
(lambda dates
(parameterize ((date-comp-type 'day-only))
(apply comp? dates))))
(define day=? (day-comp? date=?))
(define day>? (day-comp? date>?))
(define day<? (day-comp? date<?))
(define day>=? (day-comp? date>=?))
(define day<=? (day-comp? date<=?))
(define day!=? (day-comp? date!=?))
(define (date===? d1 d2 . dates)
(let ((dates (list* d1 d2 dates)))
(and (apply = (map date-zone-offset dates))
(apply date=? dates))))
(define (date->seconds d)
(time-second (date->time-utc d)))
(define (seconds->date s (tz 0))
(time-utc->date (make-time time-utc 0 s) tz))
(define (current-local-tz-offset)
(date-zone-offset (current-date)))
(define (date+ date day)
(julian-day->date (+ (date->julian-day date) day)
(date-zone-offset date)))
(define (date- d1 d2)
(- (date->julian-day d1) (date->julian-day d2)))
(define (date->alarm date)
(alarm-evt (* 1000 (date->seconds date))))
(define (date->future-alarm date (d (current-date)))
(if (date>? date d)
(date->alarm date)
#f))
(define date-comp/c
(->* (date? date?)
()
#:rest (listof date?)
boolean?))
(provide/contract
(build-date (->* (integer? (integer-in 1 12) (integer-in 1 31))
((integer-in 0 23) (integer-in 0 59) (integer-in 0 60)
exact-nonnegative-integer?
#:tz (integer-in -86400 86400))
date?))
(date->date/tz (->* (date?)
((or/c #f (integer-in -86400 86400)))
date?))
(current-local-tz-offset (-> number?))
(date-comp-type (parameter/c (or/c 'day-only 'day+time 'date 'date+tz)))
(date=? date-comp/c)
(date>? date-comp/c)
(date<? date-comp/c)
(date!=? date-comp/c)
(date>=? date-comp/c)
(date<=? date-comp/c)
(day=? date-comp/c)
(day>? date-comp/c)
(day<? date-comp/c)
(day!=? date-comp/c)
(day>=? date-comp/c)
(day<=? date-comp/c)
(date===? date-comp/c)
(date+ (-> date? (lambda (n)
(and (number? n)
(not (equal? n +inf.0))
(not (equal? n -inf.0))))
date?))
(date- (-> date? date? number?))
(date->seconds (-> date? number?))
(seconds->date (->* (exact-nonnegative-integer?)
((integer-in -86400 86400))
date?))
(date->alarm (-> date? evt?))
(date->future-alarm (->* (date?)
(date?)
(or/c #f evt?)))
)