KanoopCommonQt 2.1.1
Kanoop foundational Qt utility library
Loading...
Searching...
No Matches
timespanrange.h
1/**
2 * @brief An interval of time defined by a start and end TimeSpan offset.
3 */
4#ifndef TIMESPANRANGE_H
5#define TIMESPANRANGE_H
6#include <Kanoop/timespan.h>
7#include "kanoopcommon.h"
8
9class DateRange;
10
11/**
12 * @brief An interval of time defined by a start TimeSpan offset and an end TimeSpan offset.
13 *
14 * Useful for windowing or slicing time-series data. All arithmetic operators shift both
15 * endpoints by the same delta. The inner List class provides consolidated() to merge
16 * overlapping or adjacent ranges into a minimal non-overlapping set.
17 */
18class KANOOP_EXPORT TimeSpanRange
19{
20public:
21 /** @brief Default constructor — creates an invalid (default-constructed) range. */
23
24 /**
25 * @brief Construct a range from explicit start and end offsets.
26 * @param startOffset Start of the range
27 * @param endOffset End of the range
28 */
29 TimeSpanRange(const TimeSpan& startOffset, const TimeSpan& endOffset) :
30 _startOffset(startOffset), _endOffset(endOffset) {}
31
32 /**
33 * @brief Construct a range from an absolute QDateTime start and a duration.
34 * @param startTime Start time (converted to a millisecond-epoch offset)
35 * @param duration Length of the range
36 */
37 TimeSpanRange(const QDateTime& startTime, const TimeSpan& duration) :
38 _startOffset(TimeSpan::fromMilliseconds(startTime.toMSecsSinceEpoch())),
39 _endOffset(TimeSpan::fromMilliseconds(startTime.toMSecsSinceEpoch()) + duration) {}
40
41 /**
42 * @brief Copy constructor.
43 * @param other Range to copy
44 */
46
47 /**
48 * @brief Construct a range centred on a midpoint with a given total duration.
49 * @param midpoint Centre of the range
50 * @param duration Total length of the range
51 * @return TimeSpanRange spanning [midpoint − duration/2, midpoint + duration/2]
52 */
53 static TimeSpanRange fromMidpoint(const TimeSpan& midpoint, const TimeSpan& duration);
54
55 /**
56 * @brief Construct a TimeSpanRange from a DateRange.
57 * @param dateRange Source date range
58 * @return Equivalent TimeSpanRange expressed as millisecond-epoch offsets
59 */
60 static TimeSpanRange fromDateRange(const DateRange& dateRange);
61
62 /**
63 * @brief Construct a range from a start offset and a duration.
64 * @param startOffset Start of the range
65 * @param duration Length of the range
66 * @return TimeSpanRange spanning [startOffset, startOffset + duration]
67 */
68 static TimeSpanRange fromStartAndDuration(const TimeSpan& startOffset, const TimeSpan& duration);
69
70 /**
71 * @brief Copy assignment.
72 * @param other Range to copy
73 * @return Reference to this range
74 */
76
77 /**
78 * @brief Shift both endpoints forward by a TimeSpan delta.
79 * @param other Amount to add to both endpoints
80 * @return Shifted range
81 */
82 TimeSpanRange operator+(const TimeSpan& other) const;
83
84 /**
85 * @brief Shift both endpoints backward by a TimeSpan delta.
86 * @param other Amount to subtract from both endpoints
87 * @return Shifted range
88 */
89 TimeSpanRange operator-(const TimeSpan& other) const;
90
91 /**
92 * @brief Add-assign a TimeSpan delta to both endpoints.
93 * @param other Amount to add
94 */
95 void operator+=(const TimeSpan& other);
96 /**
97 * @brief Subtract-assign a TimeSpan delta from both endpoints.
98 * @param other Amount to subtract
99 */
100 void operator-=(const TimeSpan& other);
101
102 /**
103 * @brief Equality comparison.
104 * @param other Range to compare with
105 * @return true if both ranges are equal
106 */
107 bool operator==(const TimeSpanRange& other) const;
108 /**
109 * @brief Inequality comparison.
110 * @param other Range to compare with
111 * @return true if both ranges differ
112 */
113 bool operator!=(const TimeSpanRange& other) const;
114
115 /**
116 * @brief Return the start offset.
117 * @return Start TimeSpan
118 */
119 TimeSpan startOffset() const { return _startOffset; }
120
121 /**
122 * @brief Set the start offset.
123 * @param value New start TimeSpan
124 */
125 void setStartOffset(const TimeSpan& value) { _startOffset = value; }
126
127 /**
128 * @brief Return the end offset.
129 * @return End TimeSpan
130 */
131 TimeSpan endOffset() const { return _endOffset; }
132
133 /**
134 * @brief Set the end offset.
135 * @param value New end TimeSpan
136 */
137 void setEndOffset(const TimeSpan& value) { _endOffset = value; }
138
139 /**
140 * @brief Return the duration of this range (end − start).
141 * @return Duration TimeSpan
142 */
143 TimeSpan duration() const { return _endOffset - _startOffset; }
144
145 /**
146 * @brief Return the midpoint of this range.
147 * @return Midpoint TimeSpan
148 */
149 TimeSpan midpoint() const { return _startOffset + (duration() / 2); }
150
151 /**
152 * @brief Test whether a time offset falls within this range (inclusive).
153 * @param time TimeSpan offset to test
154 * @return true if startOffset ≤ time ≤ endOffset
155 */
156 bool contains(const TimeSpan& time) const { return time >= _startOffset && time <= _endOffset; }
157
158 /**
159 * @brief Test whether another range is entirely contained within this one.
160 * @param other Range to test
161 * @return true if both endpoints of other lie within this range
162 */
163 bool contains(const TimeSpanRange& other) const { return contains(other.startOffset()) && contains(other.endOffset()); }
164
165 /**
166 * @brief Return the portion of another range that overlaps this range.
167 * @param other Range to intersect with
168 * @return Intersecting sub-range
169 */
171
172 /**
173 * @brief Return the union of this range and another, spanning both.
174 * @param other Range to merge with
175 * @return Merged range from the earlier start to the later end
176 */
177 TimeSpanRange merged(const TimeSpanRange& other) const;
178
179 /**
180 * @brief Return the union of two ranges, spanning both.
181 * @param a First range
182 * @param b Second range
183 * @return Merged range
184 */
185 static TimeSpanRange merged(const TimeSpanRange& a, const TimeSpanRange& b) { return a.merged(b); }
186
187 /**
188 * @brief Format this range as a human-readable string.
189 * @return String representation of the range
190 */
191 QString toString() const;
192
193 /**
194 * @brief Return true if both endpoints are valid TimeSpan values.
195 * @return true if start and end offsets are both valid
196 */
197 bool isValid() const { return _startOffset.isValid() && _endOffset.isValid(); }
198
199 /**
200 * @brief A QList of TimeSpanRange objects with a consolidated() helper.
201 */
202 class List : public QList<TimeSpanRange>
203 {
204 public:
205 /**
206 * @brief Merge overlapping or adjacent ranges into a minimal sorted non-overlapping list.
207 * @return New List with all overlapping ranges merged
208 */
210 {
211 List result;
212 List sorted = *this;
213 std::sort(sorted.begin(), sorted.end(), [](const TimeSpanRange& a, const TimeSpanRange& b) { return a.startOffset() < b.startOffset(); });
214
215 if(sorted.count() < 2) {
216 return sorted;
217 }
218
219 TimeSpanRange current = first();
220
221 for (int i = 1; i < size(); ++i) {
222 const TimeSpanRange& next = (*this)[i];
223
224 if (current.endOffset() >= next.startOffset()) {
225 current = TimeSpanRange(
226 current.startOffset(),
227 std::max(current.endOffset(), next.endOffset())
228 );
229 }
230 else {
231 result.append(current);
232 current = next;
233 }
234 }
235 result.append(current);
236
237 return result;
238 }
239 };
240
241private:
242 TimeSpan _startOffset;
243 TimeSpan _endOffset;
244};
245
246#endif // TIMESPANRANGE_H
A time range defined by a start and end QDateTime.
Definition daterange.h:18
A QList of TimeSpanRange objects with a consolidated() helper.
List consolidated() const
Merge overlapping or adjacent ranges into a minimal sorted non-overlapping list.
An interval of time defined by a start TimeSpan offset and an end TimeSpan offset.
TimeSpan startOffset() const
Return the start offset.
TimeSpanRange subRange(const TimeSpanRange &other) const
Return the portion of another range that overlaps this range.
static TimeSpanRange fromStartAndDuration(const TimeSpan &startOffset, const TimeSpan &duration)
Construct a range from a start offset and a duration.
TimeSpan midpoint() const
Return the midpoint of this range.
static TimeSpanRange merged(const TimeSpanRange &a, const TimeSpanRange &b)
Return the union of two ranges, spanning both.
bool contains(const TimeSpanRange &other) const
Test whether another range is entirely contained within this one.
void setStartOffset(const TimeSpan &value)
Set the start offset.
static TimeSpanRange fromMidpoint(const TimeSpan &midpoint, const TimeSpan &duration)
Construct a range centred on a midpoint with a given total duration.
static TimeSpanRange fromDateRange(const DateRange &dateRange)
Construct a TimeSpanRange from a DateRange.
QString toString() const
Format this range as a human-readable string.
TimeSpanRange(const TimeSpan &startOffset, const TimeSpan &endOffset)
Construct a range from explicit start and end offsets.
void operator+=(const TimeSpan &other)
Add-assign a TimeSpan delta to both endpoints.
TimeSpan endOffset() const
Return the end offset.
bool operator==(const TimeSpanRange &other) const
Equality comparison.
TimeSpan duration() const
Return the duration of this range (end − start).
void setEndOffset(const TimeSpan &value)
Set the end offset.
TimeSpanRange operator+(const TimeSpan &other) const
Shift both endpoints forward by a TimeSpan delta.
TimeSpanRange(const QDateTime &startTime, const TimeSpan &duration)
Construct a range from an absolute QDateTime start and a duration.
bool contains(const TimeSpan &time) const
Test whether a time offset falls within this range (inclusive).
TimeSpanRange(const TimeSpanRange &other)
Copy constructor.
TimeSpanRange & operator=(const TimeSpanRange &other)
Copy assignment.
TimeSpanRange operator-(const TimeSpan &other) const
Shift both endpoints backward by a TimeSpan delta.
void operator-=(const TimeSpan &other)
Subtract-assign a TimeSpan delta from both endpoints.
TimeSpanRange merged(const TimeSpanRange &other) const
Return the union of this range and another, spanning both.
bool isValid() const
Return true if both endpoints are valid TimeSpan values.
bool operator!=(const TimeSpanRange &other) const
Inequality comparison.
TimeSpanRange()
Default constructor — creates an invalid (default-constructed) range.
TimeSpan.
Definition timespan.h:42