0
# Duration and Period Building
1
2
Fluent builder system for creating durations and periods with natural language syntax and arithmetic operations. The duration building system distinguishes between precise time-based durations and calendar-based periods.
3
4
## Capabilities
5
6
### DurationBuilder Class
7
8
Core builder class for creating and manipulating durations with fluent syntax.
9
10
```scala { .api }
11
/**
12
* Builder for creating durations and periods with fluid syntax
13
* @param underlying The underlying Period object
14
*/
15
class DurationBuilder(val underlying: Period) extends AnyVal {
16
// Builder arithmetic - maintains DurationBuilder type
17
def +(that: DurationBuilder): DurationBuilder
18
def -(that: DurationBuilder): DurationBuilder
19
20
// Relative time operations
21
def ago(): DateTime
22
def later(): DateTime
23
def from(dt: DateTime): DateTime
24
def before(dt: DateTime): DateTime
25
26
// Conversion methods
27
def standardDuration: Duration
28
def toDuration: Duration
29
def toPeriod: Period
30
31
// Period arithmetic - returns Period
32
def -(period: ReadablePeriod): Period
33
def +(period: ReadablePeriod): Period
34
35
// Time value extraction
36
def millis: Long
37
def seconds: Long
38
39
// Duration arithmetic - returns Duration
40
def -(amount: Long): Duration
41
def -(amount: ReadableDuration): Duration
42
def +(amount: Long): Duration
43
def +(amount: ReadableDuration): Duration
44
}
45
```
46
47
**DurationBuilder Object Factory:**
48
49
```scala { .api }
50
object DurationBuilder {
51
def apply(underlying: Period): DurationBuilder
52
}
53
```
54
55
**Usage Examples:**
56
57
```scala
58
import com.github.nscala_time.time.Imports._
59
60
// Create duration builders
61
val duration1 = 2.hours + 30.minutes
62
val duration2 = 1.hour + 45.minutes
63
64
// Builder arithmetic
65
val combined = duration1 + duration2 // 4 hours 15 minutes
66
val difference = duration1 - duration2 // 45 minutes
67
68
// Relative time operations
69
val pastTime = duration1.ago() // 2.5 hours ago
70
val futureTime = duration1.later() // 2.5 hours from now
71
val fromSpecific = duration1.from(DateTime.parse("2023-01-01T12:00:00"))
72
73
// Conversion to different types
74
val asDuration = duration1.toDuration
75
val asPeriod = duration1.toPeriod
76
val millisValue = duration1.millis
77
val secondsValue = duration1.seconds
78
```
79
80
### Integer Duration Extensions
81
82
Extension methods for integers to create duration builders and periods using natural language syntax.
83
84
```scala { .api }
85
/**
86
* Adds time unit methods to integers for creating durations and periods
87
* @param underlying The underlying integer value
88
*/
89
implicit class RichInt(val underlying: Int) extends AnyVal {
90
// Precise time units - return DurationBuilder (can be used as Duration or Period)
91
def millis: DurationBuilder
92
def seconds: DurationBuilder
93
def minutes: DurationBuilder
94
def hours: DurationBuilder
95
96
// Calendar-based units - return Period (variable length based on calendar)
97
def days: Period
98
def weeks: Period
99
def months: Period
100
def years: Period
101
102
// Singular forms for natural language syntax
103
def milli: DurationBuilder
104
def second: DurationBuilder
105
def minute: DurationBuilder
106
def hour: DurationBuilder
107
def day: Period
108
def week: Period
109
def month: Period
110
def year: Period
111
112
// Period multiplication
113
def *(period: Period): Period
114
}
115
```
116
117
**Usage Examples:**
118
119
```scala
120
import com.github.nscala_time.time.Imports._
121
122
// Precise duration building (suitable for durations)
123
val preciseDuration = 2.hours + 30.minutes + 45.seconds
124
val inMillis = preciseDuration.millis // Get total milliseconds
125
126
// Calendar-based periods (variable length)
127
val calendarPeriod = 1.month + 2.weeks + 3.days
128
val multipliedPeriod = 5 * 1.day // 5 days
129
130
// Mixed usage - builders auto-convert when needed
131
val now = DateTime.now()
132
val future1 = now + 2.hours // Add precise duration
133
val future2 = now + 1.month // Add calendar period
134
val future3 = now + (1.day + 2.hours) // Mixed period and duration
135
136
// Singular forms for readability
137
val singleUnits = 1.hour + 1.minute + 1.second
138
val singlePeriods = 1.year + 1.month + 1.day
139
```
140
141
### Long Duration Extensions
142
143
Extension methods for long values providing duration conversion and arithmetic operations.
144
145
```scala { .api }
146
/**
147
* Adds duration conversion and arithmetic methods to long values
148
* @param underlying The underlying long value (treated as milliseconds)
149
*/
150
implicit class RichLong(val underlying: Long) extends AnyVal {
151
// Conversion methods
152
def toDateTime: DateTime
153
def toDuration: Duration
154
155
// Duration arithmetic operations
156
def -(duration: Duration): Duration
157
def +(duration: Duration): Duration
158
def *(duration: Duration): Duration
159
}
160
```
161
162
**Usage Examples:**
163
164
```scala
165
import com.github.nscala_time.time.Imports._
166
167
// Convert milliseconds to DateTime (Unix timestamp)
168
val timestamp = 1672531200000L // Jan 1, 2023 00:00:00 UTC
169
val dateTime = timestamp.toDateTime
170
171
// Convert milliseconds to Duration
172
val durationInMillis = 3600000L // 1 hour in milliseconds
173
val duration = durationInMillis.toDuration
174
175
// Duration arithmetic with Long values
176
val baseDuration = Duration.standardHours(2)
177
val extended = 1800000L + baseDuration // Add 30 minutes (in millis) to 2 hours
178
val reduced = 5400000L - baseDuration // Subtract 2 hours from 90 minutes
179
val multiplied = 2L * baseDuration // Multiply duration by 2
180
181
// Working with timestamps and durations
182
val currentTimeMillis = System.currentTimeMillis()
183
val currentTime = currentTimeMillis.toDateTime
184
val oneHourLater = currentTime + Duration.standardHours(1)
185
```
186
187
### Builder Implicit Conversions
188
189
Implicit conversions for seamless integration with Joda Time types.
190
191
```scala { .api }
192
/**
193
* Implicit conversions for DurationBuilder integration
194
*/
195
trait BuilderImplicits {
196
/**
197
* Automatically convert DurationBuilder to Period when Period is expected
198
*/
199
implicit def forcePeriod(builder: DurationBuilder): Period
200
201
/**
202
* Automatically convert DurationBuilder to Duration when Duration is expected
203
*/
204
implicit def forceDuration(builder: DurationBuilder): Duration
205
}
206
```
207
208
**Usage Examples:**
209
210
```scala
211
import com.github.nscala_time.time.Imports._
212
213
// Implicit conversion in action - no explicit conversion needed
214
val period: Period = 2.hours + 30.minutes // Automatically converts to Period
215
val duration: Duration = 2.hours + 30.minutes // Automatically converts to Duration
216
217
// Use in method calls expecting specific types
218
def takePeriod(p: Period): String = p.toString
219
def takeDuration(d: Duration): Long = d.getMillis
220
221
val builder = 1.hour + 30.minutes
222
val periodResult = takePeriod(builder) // Implicit conversion to Period
223
val durationResult = takeDuration(builder) // Implicit conversion to Duration
224
```
225
226
## Duration vs Period Distinction
227
228
**Duration**: Represents a precise amount of time measured in milliseconds. Always consistent regardless of when it's applied.
229
230
```scala
231
val duration = 24.hours.toDuration
232
// Always exactly 86,400,000 milliseconds
233
```
234
235
**Period**: Represents a calendar-based amount of time that can vary based on when it's applied (due to daylight saving time, leap years, different month lengths, etc.).
236
237
```scala
238
val period = 1.day
239
// Could be 23, 24, or 25 hours depending on DST transitions
240
```
241
242
**Best Practices:**
243
244
- Use **hours, minutes, seconds, millis** for precise timing operations
245
- Use **days, weeks, months, years** for calendar-based operations
246
- DurationBuilder provides flexibility to convert between both as needed