0
# Duration and Period Operations
1
2
Mathematical operations on Duration and Period objects with full operator overloading support for arithmetic, comparison, and type checking operations.
3
4
## Capabilities
5
6
### Duration Operations
7
8
Duration represents a time-based amount of time (hours, minutes, seconds, nanoseconds).
9
10
```groovy { .api }
11
/**
12
* Returns a Duration that is the specified number of seconds longer than this duration.
13
*/
14
Duration plus(Duration self, long seconds)
15
16
/**
17
* Returns a Duration that is the specified number of seconds shorter than this duration.
18
*/
19
Duration minus(Duration self, long seconds)
20
21
/**
22
* Returns a Duration that is one second longer than this duration.
23
*/
24
Duration next(Duration self)
25
26
/**
27
* Returns a Duration that is one second shorter than this duration.
28
*/
29
Duration previous(Duration self)
30
31
/**
32
* Supports the unary minus operator; equivalent to Duration.negated().
33
*/
34
Duration negative(Duration self)
35
36
/**
37
* Supports the unary plus operator; returns the absolute value of the duration.
38
*/
39
Duration positive(Duration self)
40
41
/**
42
* Supports the multiplication operator; equivalent to Duration.multipliedBy().
43
*/
44
Duration multiply(Duration self, long scalar)
45
46
/**
47
* Supports the division operator; equivalent to Duration.dividedBy().
48
*/
49
Duration div(Duration self, long scalar)
50
51
/**
52
* Returns true if this duration is positive, excluding zero.
53
*/
54
boolean isPositive(Duration self)
55
56
/**
57
* Returns true if this duration is zero or positive.
58
*/
59
boolean isNonnegative(Duration self)
60
61
/**
62
* Returns true if this duration is zero or negative.
63
*/
64
boolean isNonpositive(Duration self)
65
```
66
67
**Usage Examples:**
68
69
```groovy
70
import java.time.*
71
72
def duration = Duration.ofMinutes(30)
73
74
// Arithmetic operations using operators
75
def longer = duration + 120 // Add 120 seconds (2 minutes)
76
def shorter = duration - 300 // Subtract 300 seconds (5 minutes)
77
def doubled = duration * 2 // 60 minutes
78
def halved = duration / 2 // 15 minutes
79
80
// Unary operators
81
def negated = -duration // Negative 30 minutes
82
def absolute = +duration // Absolute value (same as positive duration)
83
84
// Navigation
85
def nextSecond = duration.next() // One second longer
86
def prevSecond = duration.previous() // One second shorter
87
88
// Type checking
89
println duration.isPositive() // true (30 minutes > 0)
90
println duration.isNonnegative() // true (30 minutes >= 0)
91
92
def zeroDuration = Duration.ZERO
93
println zeroDuration.isNonnegative() // true (0 >= 0)
94
println zeroDuration.isPositive() // false (0 not > 0)
95
96
def negativeDuration = Duration.ofMinutes(-10)
97
println negativeDuration.isNonpositive() // true (-10 minutes <= 0)
98
99
// Chaining operations
100
def result = Duration.ofHours(1)
101
.plus(1800) // Add 30 minutes
102
.multiply(2) // Double it
103
.div(3) // Divide by 3
104
println "Result: ${result.toHours()} hours, ${result.toMinutesPart()} minutes"
105
```
106
107
### Period Operations
108
109
Period represents a date-based amount of time (years, months, days).
110
111
```groovy { .api }
112
/**
113
* Returns a Period that is the specified number of days longer than this period.
114
*/
115
Period plus(Period self, long days)
116
117
/**
118
* Returns a Period that is the specified number of days shorter than this period.
119
*/
120
Period minus(Period self, long days)
121
122
/**
123
* Returns a Period that is one day longer than this period.
124
*/
125
Period next(Period self)
126
127
/**
128
* Returns a Period that is one day shorter than this period.
129
*/
130
Period previous(Period self)
131
132
/**
133
* Supports the unary minus operator; equivalent to Period.negated().
134
*/
135
Period negative(Period self)
136
137
/**
138
* Supports the unary plus operator; returns a Period with all absolute values.
139
*/
140
Period positive(Period self)
141
142
/**
143
* Supports the multiplication operator; equivalent to Period.multipliedBy().
144
*/
145
Period multiply(Period self, int scalar)
146
147
/**
148
* Returns true if this period is positive, excluding zero.
149
*/
150
boolean isPositive(ChronoPeriod self)
151
152
/**
153
* Returns true if this period is zero or positive.
154
*/
155
boolean isNonnegative(ChronoPeriod self)
156
157
/**
158
* Returns true if this period is zero or negative.
159
*/
160
boolean isNonpositive(ChronoPeriod self)
161
```
162
163
**Usage Examples:**
164
165
```groovy
166
import java.time.*
167
168
def period = Period.of(1, 6, 15) // 1 year, 6 months, 15 days
169
170
// Arithmetic operations
171
def longerPeriod = period + 10 // Add 10 days
172
def shorterPeriod = period - 5 // Subtract 5 days
173
def doubled = period * 2 // 2 years, 12 months, 30 days
174
175
// Unary operators
176
def negated = -period // -1 year, -6 months, -15 days
177
def absolute = +period // All positive values
178
179
// Navigation
180
def nextDay = period.next() // Add one day
181
def prevDay = period.previous() // Subtract one day
182
183
// Type checking
184
println period.isPositive() // true (has positive components)
185
println period.isNonnegative() // true (no negative components)
186
187
def mixedPeriod = Period.of(1, -2, 3) // 1 year, -2 months, 3 days
188
println mixedPeriod.isPositive() // false (has negative component)
189
190
def negativePeriod = Period.of(-1, -1, -1)
191
println negativePeriod.isNonpositive() // true (all components <= 0)
192
193
// Working with normalized periods
194
def normalized = Period.of(0, 14, 0).normalized() // Becomes 1 year, 2 months
195
println "Normalized: ${normalized.years} years, ${normalized.months} months"
196
```
197
198
### TemporalAmount Subscript Access
199
200
Generic access to temporal amounts using the subscript operator.
201
202
```groovy { .api }
203
/**
204
* Supports the subscript operator for accessing TemporalUnit values.
205
*/
206
long getAt(TemporalAmount self, TemporalUnit unit)
207
```
208
209
**Usage Examples:**
210
211
```groovy
212
import java.time.*
213
import java.time.temporal.ChronoUnit
214
215
def duration = Duration.ofHours(2).plusMinutes(30).plusSeconds(45)
216
def period = Period.of(2, 3, 10)
217
218
// Access duration components using subscript operator
219
def hours = duration[ChronoUnit.HOURS] // 2
220
def minutes = duration[ChronoUnit.MINUTES] // 150 (total minutes)
221
def seconds = duration[ChronoUnit.SECONDS] // 9045 (total seconds)
222
223
// Access period components using subscript operator
224
def years = period[ChronoUnit.YEARS] // 2
225
def months = period[ChronoUnit.MONTHS] // 3
226
def days = period[ChronoUnit.DAYS] // 10
227
228
println "Duration: ${hours}h ${minutes}m ${seconds}s"
229
println "Period: ${years}y ${months}m ${days}d"
230
```
231
232
### Advanced Duration Operations
233
234
Advanced usage patterns for duration arithmetic and manipulation.
235
236
**Usage Examples:**
237
238
```groovy
239
import java.time.*
240
import java.time.temporal.ChronoUnit
241
242
// Complex duration calculations
243
def workingHours = Duration.ofHours(8)
244
def breakTime = Duration.ofMinutes(30)
245
def overtime = Duration.ofHours(2)
246
247
def totalWorkTime = workingHours + (breakTime.toSeconds() / 60) + overtime.toSeconds()
248
def weeklyWork = workingHours * 5 // 5 working days
249
250
// Duration comparisons and chains
251
def shortBreak = Duration.ofMinutes(15)
252
def longBreak = Duration.ofMinutes(30)
253
254
if (shortBreak < longBreak) {
255
println "Short break is indeed shorter"
256
}
257
258
// Create durations from different units
259
def fromHours = Duration.ofHours(1)
260
def fromMinutes = Duration.ofMinutes(60)
261
def fromSeconds = Duration.ofSeconds(3600)
262
263
println "All equal: ${fromHours == fromMinutes && fromMinutes == fromSeconds}"
264
265
// Duration arithmetic with temporal objects
266
def now = Instant.now()
267
def later = now + Duration.ofMinutes(30).toSeconds() // Add duration as seconds
268
def earlier = now - (Duration.ofHours(1).toSeconds()) // Subtract duration as seconds
269
```
270
271
### Advanced Period Operations
272
273
Advanced usage patterns for period arithmetic and date manipulation.
274
275
**Usage Examples:**
276
277
```groovy
278
import java.time.*
279
280
// Complex period calculations
281
def age = Period.between(LocalDate.of(1990, 5, 15), LocalDate.now())
282
def retirement = Period.of(65, 0, 0) - age // Years until retirement
283
284
println "Age: ${age.years} years, ${age.months} months, ${age.days} days"
285
println "Years to retirement: ${retirement.years}"
286
287
// Period manipulation with dates
288
def startDate = LocalDate.of(2024, 1, 1)
289
def projectDuration = Period.of(0, 6, 15) // 6 months, 15 days
290
291
def milestones = []
292
def currentDate = startDate
293
3.times { i ->
294
milestones << currentDate
295
currentDate = currentDate + projectDuration // Add period to date
296
}
297
298
milestones.each { milestone ->
299
println "Milestone ${milestones.indexOf(milestone) + 1}: ${milestone}"
300
}
301
302
// Working with different period types
303
def yearPeriod = Period.ofYears(2)
304
def monthPeriod = Period.ofMonths(24) // Equivalent to 2 years
305
def dayPeriod = Period.ofDays(730) // Approximately 2 years
306
307
// Note: These are not automatically equivalent due to variable month/year lengths
308
println "Year period: ${yearPeriod}"
309
println "Month period: ${monthPeriod}"
310
println "Day period: ${dayPeriod}"
311
312
// Normalize to convert months to years where possible
313
def normalizedMonth = monthPeriod.normalized()
314
println "Normalized month period: ${normalizedMonth}" // 2 years, 0 months
315
```
316
317
### Integration with Temporal Objects
318
319
How Duration and Period objects integrate with temporal types for arithmetic operations.
320
321
**Usage Examples:**
322
323
```groovy
324
import java.time.*
325
326
// Using periods with dates
327
def startDate = LocalDate.of(2024, 1, 1)
328
def period = Period.of(1, 6, 10) // 1 year, 6 months, 10 days
329
330
def futureDate = startDate + period // Uses plus(Period) method
331
def pastDate = startDate - period // Uses minus(Period) method
332
333
// Using durations with time-based objects
334
def startTime = LocalTime.of(9, 0)
335
def duration = Duration.ofHours(2).plusMinutes(30)
336
337
def endTime = startTime + duration.toSeconds() // Add as seconds
338
def earlierTime = startTime - duration.toSeconds()
339
340
// Complex temporal arithmetic
341
def meeting = LocalDateTime.of(2024, 12, 25, 14, 0)
342
def preparation = Duration.ofMinutes(30)
343
def followUp = Period.ofDays(3)
344
345
def prepStart = meeting - preparation.toSeconds()
346
def followUpDate = meeting.toLocalDate() + followUp
347
348
println "Prep starts: ${prepStart}"
349
println "Follow-up date: ${followUpDate}"
350
```