0
# Ordering and Comparisons
1
2
Built-in ordering instances and comparison operators for all date/time types enabling seamless integration with Scala collections. Provides type-safe chronological ordering and comparison operations.
3
4
## Capabilities
5
6
### Date/Time Ordering Instances
7
8
Pre-defined ordering instances for all major date/time types.
9
10
```scala { .api }
11
/**
12
* Ordering instances for date/time types
13
*/
14
trait OrderingImplicits extends LowPriorityOrderingImplicits {
15
implicit val DateTimeOrdering: Ordering[DateTime]
16
implicit val LocalDateOrdering: Ordering[LocalDate]
17
implicit val LocalTimeOrdering: Ordering[LocalTime]
18
implicit val LocalDateTimeOrdering: Ordering[LocalDateTime]
19
implicit val DurationOrdering: Ordering[Duration]
20
}
21
```
22
23
### Generic Ordering Support
24
25
Low-priority implicit ordering for Joda Time type hierarchies.
26
27
```scala { .api }
28
/**
29
* Generic ordering support for Joda Time types
30
*/
31
trait LowPriorityOrderingImplicits {
32
implicit def ReadableInstantOrdering[A <: ReadableInstant]: Ordering[A]
33
implicit def ReadablePartialOrdering[A <: ReadablePartial]: Ordering[A]
34
implicit def BaseSingleFieldPeriodOrdering[A <: BaseSingleFieldPeriod]: Ordering[A]
35
implicit def ReadableDurationOrdering[A <: ReadableDuration]: Ordering[A]
36
}
37
```
38
39
**Usage Examples:**
40
41
```scala
42
import com.github.nscala_time.time.Imports._
43
44
// DateTime ordering
45
val dt1 = DateTime.parse("2023-01-01T10:00:00")
46
val dt2 = DateTime.parse("2023-01-01T11:00:00")
47
val dt3 = DateTime.parse("2023-01-02T10:00:00")
48
49
// Direct comparisons
50
val isBefore = dt1 < dt2 // true
51
val isAfter = dt2 > dt1 // true
52
val isEqual = dt1 == dt1 // true
53
54
// Sorting collections
55
val dateTimes = List(dt3, dt1, dt2)
56
val sorted = dateTimes.sorted // List(dt1, dt2, dt3) - chronological order
57
val reverse = dateTimes.sorted(Ordering[DateTime].reverse)
58
59
// LocalDate ordering
60
val ld1 = LocalDate.parse("2023-01-01")
61
val ld2 = LocalDate.parse("2023-01-15")
62
val ld3 = LocalDate.parse("2023-02-01")
63
64
val localDates = List(ld3, ld1, ld2)
65
val sortedDates = localDates.sorted // Chronological order
66
67
// Duration ordering
68
val dur1 = Duration.standardHours(1)
69
val dur2 = Duration.standardHours(2)
70
val dur3 = Duration.standardMinutes(30)
71
72
val durations = List(dur2, dur3, dur1)
73
val sortedDurations = durations.sorted // List(dur3, dur1, dur2) - by length
74
```
75
76
### Collection Operations
77
78
Integration with Scala collections using built-in ordering.
79
80
```scala
81
import com.github.nscala_time.time.Imports._
82
83
// Finding min/max in collections
84
val times = List(
85
DateTime.parse("2023-01-15T10:00:00"),
86
DateTime.parse("2023-01-01T10:00:00"),
87
DateTime.parse("2023-02-01T10:00:00")
88
)
89
90
val earliest = times.min // 2023-01-01T10:00:00
91
val latest = times.max // 2023-02-01T10:00:00
92
93
// Filtering with comparisons
94
val cutoffDate = DateTime.parse("2023-01-15T00:00:00")
95
val afterCutoff = times.filter(_ > cutoffDate)
96
val beforeCutoff = times.filter(_ < cutoffDate)
97
98
// Grouping by comparison
99
val grouped = times.groupBy(_ > cutoffDate)
100
// Map(false -> List(early dates), true -> List(late dates))
101
102
// Working with ranges
103
val startDate = LocalDate.parse("2023-01-01")
104
val endDate = LocalDate.parse("2023-01-31")
105
106
// Custom range operations
107
def isInRange(date: LocalDate, start: LocalDate, end: LocalDate): Boolean = {
108
date >= start && date <= end
109
}
110
111
val testDate = LocalDate.parse("2023-01-15")
112
val inRange = isInRange(testDate, startDate, endDate) // true
113
```
114
115
### Comparison Operators
116
117
All date/time types support standard comparison operators through implicit conversions.
118
119
```scala
120
import com.github.nscala_time.time.Imports._
121
122
val now = DateTime.now()
123
val later = now + 1.hour
124
val earlier = now - 1.hour
125
126
// All comparison operators work
127
val isLess = earlier < now // true
128
val isLessOrEqual = now <= later // true
129
val isGreater = later > now // true
130
val isGreaterOrEqual = now >= earlier // true
131
val isEqual = now == now // true
132
val isNotEqual = now != later // true
133
134
// Works with all date/time types
135
val date1 = LocalDate.now()
136
val date2 = date1 + 1.day
137
138
val dateComparison = date1 < date2 // true
139
140
val time1 = LocalTime.now()
141
val time2 = time1 + 1.hour
142
143
val timeComparison = time1 < time2 // true
144
```
145
146
### Sorting and Priority Queues
147
148
Using ordering with advanced collection operations.
149
150
```scala
151
import com.github.nscala_time.time.Imports._
152
import scala.collection.mutable.PriorityQueue
153
154
// Priority queue with DateTime (earliest first)
155
implicit val earliestFirst: Ordering[DateTime] = Ordering[DateTime].reverse
156
val scheduledTasks = PriorityQueue[DateTime]()
157
158
scheduledTasks.enqueue(DateTime.now() + 1.hour)
159
scheduledTasks.enqueue(DateTime.now() + 30.minutes)
160
scheduledTasks.enqueue(DateTime.now() + 2.hours)
161
162
val nextTask = scheduledTasks.dequeue() // Returns earliest (30 minutes from now)
163
164
// Sorting with custom criteria
165
case class Event(name: String, time: DateTime)
166
167
val events = List(
168
Event("Meeting", DateTime.now() + 1.hour),
169
Event("Lunch", DateTime.now() + 30.minutes),
170
Event("Call", DateTime.now() + 2.hours)
171
)
172
173
// Sort by time
174
val sortedByTime = events.sortBy(_.time)
175
176
// Custom ordering for events
177
implicit val eventOrdering: Ordering[Event] = Ordering.by(_.time)
178
val sortedEvents = events.sorted
179
```
180
181
### Interval Comparisons
182
183
Working with intervals and their ordering relationships.
184
185
```scala
186
import com.github.nscala_time.time.Imports._
187
188
val now = DateTime.now()
189
val interval1 = now to (now + 1.hour)
190
val interval2 = (now + 30.minutes) to (now + 90.minutes)
191
val interval3 = (now + 2.hours) to (now + 3.hours)
192
193
// Interval relationships
194
val overlaps = interval1.overlaps(interval2) // true
195
val contains = interval1.contains(now + 15.minutes) // true
196
val isBefore = interval1.isBefore(interval3) // true
197
val isAfter = interval3.isAfter(interval1) // true
198
199
// Sorting intervals by start time
200
val intervals = List(interval3, interval1, interval2)
201
val sortedByStart = intervals.sortBy(_.getStart)
202
203
// Sorting by duration
204
val sortedByDuration = intervals.sortBy(_.toDurationMillis)
205
```
206
207
### Custom Ordering Examples
208
209
Creating custom ordering instances for complex scenarios.
210
211
```scala
212
import com.github.nscala_time.time.Imports._
213
214
// Custom ordering: sort by time of day, ignoring date
215
implicit val timeOfDayOrdering: Ordering[DateTime] =
216
Ordering.by(dt => dt.getMillisOfDay)
217
218
val dateTimes = List(
219
DateTime.parse("2023-01-01T14:30:00"),
220
DateTime.parse("2023-02-15T09:15:00"),
221
DateTime.parse("2023-12-25T16:45:00")
222
)
223
224
val sortedByTimeOfDay = dateTimes.sorted(timeOfDayOrdering)
225
// Results in: 09:15, 14:30, 16:45 regardless of date
226
227
// Custom ordering: sort LocalDate by day of year
228
implicit val dayOfYearOrdering: Ordering[LocalDate] =
229
Ordering.by(ld => ld.getDayOfYear)
230
231
// Custom ordering: reverse chronological order
232
implicit val reverseChronological: Ordering[DateTime] =
233
Ordering[DateTime].reverse
234
235
// Multiple criteria ordering
236
case class Appointment(date: LocalDate, time: LocalTime, priority: Int)
237
238
implicit val appointmentOrdering: Ordering[Appointment] =
239
Ordering.by(a => (a.date, a.time, -a.priority)) // Date, then time, then priority (high first)
240
```
241
242
### Type-Safe Comparisons
243
244
The ordering system ensures type safety in comparisons.
245
246
```scala
247
import com.github.nscala_time.time.Imports._
248
249
val dateTime = DateTime.now()
250
val localDate = LocalDate.now()
251
val duration = Duration.standardHours(1)
252
253
// These work - same types
254
val dateTimeComparison = dateTime < (dateTime + 1.hour) // OK
255
val localDateComparison = localDate < (localDate + 1.day) // OK
256
val durationComparison = duration < Duration.standardHours(2) // OK
257
258
// These would be compile errors - different types
259
// val mixedComparison1 = dateTime < localDate // Compile error
260
// val mixedComparison2 = dateTime < duration // Compile error
261
262
// Conversions needed for cross-type comparisons
263
val dateTimeFromLocal = localDate.toDateTimeAtCurrentTime()
264
val validComparison = dateTime < dateTimeFromLocal // OK after conversion
265
```