--- /dev/null
+USING: arrays calendar calendar.ranges kernel tools.test ;
+
+{
+ {
+ T{ timestamp { year 2023 } { month 6 } { day 21 } }
+ T{ timestamp { year 2023 } { month 6 } { day 22 } }
+ T{ timestamp { year 2023 } { month 6 } { day 23 } }
+ T{ timestamp { year 2023 } { month 6 } { day 24 } }
+ T{ timestamp { year 2023 } { month 6 } { day 25 } }
+ T{ timestamp { year 2023 } { month 6 } { day 26 } }
+ T{ timestamp { year 2023 } { month 6 } { day 27 } }
+ T{ timestamp { year 2023 } { month 6 } { day 28 } }
+ T{ timestamp { year 2023 } { month 6 } { day 29 } }
+ T{ timestamp { year 2023 } { month 6 } { day 30 } }
+ T{ timestamp { year 2023 } { month 7 } { day 1 } }
+ T{ timestamp { year 2023 } { month 7 } { day 2 } }
+ T{ timestamp { year 2023 } { month 7 } { day 3 } }
+ T{ timestamp { year 2023 } { month 7 } { day 4 } }
+ }
+} [
+ 2023 06 21 <date-utc> dup 2 weeks time+
+ 1 days <timestamp-range> >array
+] unit-test
--- /dev/null
+! Copyright (C) 2023 John Benediktsson
+! See https://factorcode.org/license.txt for BSD license
+
+USING: accessors calendar kernel math math.functions sequences
+sequences.private ;
+
+IN: calendar.ranges
+
+TUPLE: timestamp-range
+ { from timestamp read-only }
+ { length integer read-only }
+ { step duration read-only } ;
+
+:: <timestamp-range> ( from to step -- timestamp-range )
+ from
+ to from time- step [ duration>seconds ] bi@ /f floor >integer
+ step
+ timestamp-range boa ;
+
+
+M: timestamp-range length length>> ;
+
+M: timestamp-range nth-unsafe
+ [ step>> duration* ] keep from>> time+ ;
+
+INSTANCE: timestamp-range sequence