aboutsummaryrefslogtreecommitdiff
path: root/module/vcomponent/datetime.scm
blob: b394064405368c13c3cba4c2f7de2f74fb0ced26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
(define-module (vcomponent datetime)
  #:use-module (vcomponent base)
  #:use-module (datetime)
  #:use-module (datetime util)
  #:use-module (util)

  #:export (#;parse-datetime
            event-overlaps?
            overlapping?
            event-contains?
            ev-time<?)
  )

;;; date time pointer
#;
(define (parse-datetime dtime)
  "Parse the given date[time] string into a date object."
  (string->date
   dtime (case (string-length dtime)
           ((8)  "~Y~m~d")              ; All day
           ((15) "~Y~m~dT~H~M~S")       ; "local" or TZID-param
           ((16) "~Y~m~dT~H~M~S~z"))))  ; UTC-time

(define (event-overlaps? event begin end)
  "Returns if the event overlaps the timespan.
Event must have the DTSTART and DTEND attribute set."
  (timespan-overlaps? (attr event 'DTSTART)
                      (attr event 'DTEND)
                      begin end))

(define (overlapping? event-a event-b)
  (timespan-overlaps? (attr event-a 'DTSTART)
                      (attr event-a 'DTEND)
                      (attr event-b 'DTSTART)
                      (attr event-b 'DTEND)))

(define (event-contains? ev date/-time)
  "Does event overlap the date that contains time."
  (let* ((start (as-date date/-time))
         (end (add-day start)))
    (event-overlaps? ev start end)))

(define-public (ev-time<? a b)
  (date/-time<? (attr a 'DTSTART)
                (attr b 'DTSTART)))

;; Returns length of the event @var{e}, as a time-duration object.
(define-public (event-length e)
  (if (not (attr e 'DTEND))
      (datetime date:
                (if (date? (attr e 'DTSTART))
                    #24:00:00
                    #01:00:00))
      ((if (date? (attr e 'DTSTART))
           date-difference datetime-difference)
       (attr e 'DTEND) (attr e 'DTSTART))))

(define-public (event-length/clamped start-date end-date e)
  (if (date? (attr e 'DTSTART))
      (date-difference (date-min (date+ end-date (date day: 1))
                                 (attr e 'DTEND))
                       (date-max start-date
                                 (attr e 'DTSTART)))
      (datetime-difference (datetime-min (datetime date: (date+ end-date (date day: 1)))
                                         (get-datetime (attr e 'DTEND)))
                           (datetime-max (datetime date: start-date)
                                         (get-datetime (attr e 'DTSTART))))))

;; Returns the length of the part of @var{e} which is within the day
;; starting at the time @var{start-of-day}.
;; currently the secund argument is a date, but should possibly be changed
;; to a datetime to allow for more explicit TZ handling?
(define-public (event-length/day date e)
  ;; TODO date= > 2 elements
  (cond [(and (date= (as-date (attr e 'DTSTART))
                 (as-date (attr e 'DTEND)))
              (date= (as-date (attr e 'DTSTART))
                     date))
         (time- (as-time (attr e 'DTEND))
                (as-time (attr e 'DTSTART)))]
        ;; Starts today, end in future day
        [(date= (as-date (attr e 'DTSTART))
                date)
         (time- #24:00:00 (as-time (attr e 'DTSTART)))]
        ;; Ends today, start earlier day
        [(date= (as-date (attr e 'DTEND))
                date)
         (as-time (attr e 'DTEND))]
        ;; start earlier date, end later date
        [else #24:00:00]))


;; 22:00 - 03:00
;; 2h för dag 1
;; 3h för dag 2

;; An event is considered long if it's DTSTART (and thereby DTEND) lacks a time component,
;; or if the total length of the event is greater than 24h.
;; For practical purposes, an event being long means that it shouldn't be rendered as a part
;; of a regular day.
(define-public (long-event? ev)
  (or (date? (attr ev 'DTSTART))
      (datetime<= (datetime date: (date day: 1))
                  (datetime-difference (attr ev 'DTEND)
                                       (attr ev 'DTSTART)))))