Skip to content

Instantly share code, notes, and snippets.

@henryw374
Created December 9, 2022 14:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henryw374/a68595033e2a4871f7a9c2f04c01dddd to your computer and use it in GitHub Desktop.
Save henryw374/a68595033e2a4871f7a9c2f04c01dddd to your computer and use it in GitHub Desktop.
(ns contiguous-spans
"takes pre-sorted dates and returns contiguous periods contained therein.
see comment block for demo
"
(:require [tick.core :as t]))
(defn contiguous-spans
"takes pre-sorted dates and returns contiguous periods contained.
dates a and b are contiguous if a plus span-length is equal to b "
[span-length xs]
(loop [spans []
remaining xs]
(if-not (seq remaining)
spans
(let [[span remaining2] (->> remaining
(map vector
(iterate #(t/>> % span-length)
(first remaining)))
(split-with #(apply = %))
(map #(map second %)))
[span2 remaining3] (if (empty? span)
(let [[start remaining] remaining2]
[{:start start
:end (t/>> start span-length)}
remaining])
[{:start (first span)
:end (t/>> (last span) span-length)}
remaining2])]
(recur (conj spans span2)
remaining3)))))
(comment
#_(def sample (concat (->> (-> (t/now) (t/truncate :hours))
(iterate #(t/>> % (t/new-duration 1 :hours)))
(take 5))
(->> (-> (t/now) (t/truncate :hours) (t/<< (t/new-duration 24 :hours)))
(iterate #(t/>> % (t/new-duration 1 :hours)))
(take 5))
[(-> (t/now) (t/truncate :hours) (t/<< (t/new-duration 48 :hours)))]))
(def sample
[(t/instant "2022-12-07T13:00:00Z")
(t/instant "2022-12-08T13:00:00Z")
(t/instant "2022-12-08T14:00:00Z")
(t/instant "2022-12-08T15:00:00Z")
(t/instant "2022-12-08T16:00:00Z")
(t/instant "2022-12-08T17:00:00Z")
(t/instant "2022-12-09T13:00:00Z")
(t/instant "2022-12-09T14:00:00Z")
(t/instant "2022-12-09T15:00:00Z")
(t/instant "2022-12-09T16:00:00Z")
(t/instant "2022-12-09T17:00:00Z")])
(=
[{:start (t/instant "2022-12-07T13:00:00Z"), :end (t/instant "2022-12-07T14:00:00Z")}
{:start (t/instant "2022-12-08T13:00:00Z"), :end (t/instant "2022-12-08T18:00:00Z")}
{:start (t/instant "2022-12-09T13:00:00Z"), :end (t/instant "2022-12-09T18:00:00Z")}]
(contiguous-spans (t/new-duration 1 :hours) sample))
(widdindustries.capture/capt
'(contiguous-spans (t/new-duration 1 :hours) (sort sample)))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment