Skip to content

Commit 20653c1

Browse files
committed
fixed the one-off errors in rounding, and resolved the test values to correct increments for roundUp
1 parent 3772f35 commit 20653c1

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

Sources/SwiftVizScale/NiceValue.swift

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,15 @@ public enum DateMagnitude: Equatable {
236236
case months
237237
/// Years.
238238
case years
239-
239+
240240
static let subsecondThreshold: PartialRangeUpTo<Double> = ..<1
241241
static let secondsThreshold: Range<Double> = 1 ..< 60
242242
static let minutesThreshold: Range<Double> = 60 ..< 60 * 60
243243
static let hoursThreshold: Range<Double> = 60 * 60 ..< 60 * 60 * 24
244244
static let daysThreshold: Range<Double> = 60 * 60 * 24 ..< 60 * 60 * 24 * 28
245245
static let monthsThreshold: Range<Double> = 60 * 60 * 24 * 28 ..< 60 * 60 * 24 * 365
246246
static let yearsThreshold: PartialRangeFrom<Double> = (60 * 60 * 24 * 365)...
247-
247+
248248
/// The value of the date magnitude in seconds per increment.
249249
public var seconds: Double {
250250
switch self {
@@ -299,6 +299,7 @@ public extension Date {
299299
case .subsecond:
300300
if let asNanoseconds = components.nanosecond {
301301
components.nanosecond = Int.niceVersion(for: asNanoseconds, trendTowardsZero: true)
302+
assert(components.isValidDate)
302303
}
303304
assert(components.isValidDate)
304305
return components.date
@@ -307,6 +308,7 @@ public extension Date {
307308
if let stepSize = stepSize, let seconds = components.second {
308309
let valueRoundedByStep = floor(Double(seconds) / stepSize) * stepSize
309310
components.setValue(Int(valueRoundedByStep), for: .second)
311+
assert(components.isValidDate)
310312
}
311313
assert(components.isValidDate)
312314
return components.date
@@ -317,6 +319,7 @@ public extension Date {
317319
let stepSizeInMinutes = stepSize / 60
318320
let valueRoundedByStep = floor(Double(minutes) / stepSizeInMinutes) * stepSizeInMinutes
319321
components.setValue(Int(valueRoundedByStep), for: .minute)
322+
assert(components.isValidDate)
320323
}
321324
assert(components.isValidDate)
322325
return components.date
@@ -328,6 +331,7 @@ public extension Date {
328331
let stepSizeInHours = stepSize / (60 * 60)
329332
let valueRoundedByStep = floor(Double(hours) / stepSizeInHours) * stepSizeInHours
330333
components.setValue(Int(valueRoundedByStep), for: .hour)
334+
assert(components.isValidDate)
331335
}
332336
assert(components.isValidDate)
333337
return components.date
@@ -339,7 +343,12 @@ public extension Date {
339343
if let stepSize = stepSize, let days = components.day {
340344
let stepSizeInDays = stepSize / (24 * 60 * 60)
341345
let valueRoundedByStep = floor(Double(days) / stepSizeInDays) * stepSizeInDays
342-
components.setValue(Int(valueRoundedByStep), for: .day)
346+
if valueRoundedByStep < 1.0 {
347+
components.setValue(1, for: .day)
348+
} else {
349+
components.setValue(Int(valueRoundedByStep), for: .day)
350+
}
351+
assert(components.isValidDate)
343352
}
344353
assert(components.isValidDate)
345354
return components.date
@@ -352,7 +361,12 @@ public extension Date {
352361
if let stepSize = stepSize, let months = components.month {
353362
let stepSizeInMonths = stepSize / (28 * 24 * 60 * 60)
354363
let valueRoundedByStep = floor(Double(months) / stepSizeInMonths) * stepSizeInMonths
355-
components.setValue(Int(valueRoundedByStep), for: .month)
364+
if valueRoundedByStep < 1.0 {
365+
components.setValue(1, for: .month)
366+
} else {
367+
components.setValue(Int(valueRoundedByStep), for: .month)
368+
}
369+
assert(components.isValidDate)
356370
}
357371
assert(components.isValidDate)
358372
return components.date
@@ -367,7 +381,7 @@ public extension Date {
367381
return components.date
368382
}
369383
}
370-
384+
371385
/// Returns a date based on the current value, rounded 'up' to the next incremental step value.
372386
/// - Parameters:
373387
/// - magnitude: The magnitude to which to round.
@@ -376,13 +390,13 @@ public extension Date {
376390
func roundUp(magnitude: DateMagnitude, calendar: Calendar, stepSize: Double? = nil) -> Self? {
377391
let incDate: Date
378392
if let stepSize = stepSize, stepSize >= magnitude.seconds {
379-
incDate = self+stepSize
393+
incDate = self + stepSize
380394
} else {
381-
incDate = self+magnitude.seconds
395+
incDate = self + magnitude.seconds
382396
}
383397
return incDate.round(magnitude: magnitude, calendar: calendar, stepSize: stepSize)
384398
}
385-
399+
386400
/// Returns a nice step size for the magnitude of date range you provide.
387401
/// - Parameters:
388402
/// - step: The step size (in seconds) for the date increment.

Tests/SwiftVizScaleTests/DateNiceValueTests.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,12 @@ final class DateNiceValueTests: XCTestCase {
227227
)
228228

229229
XCTAssertEqual(
230-
formatter.string(from: now.round(magnitude: .hours, calendar: testCal, stepSize: 2 * 60 * 60)!),
230+
formatter.string(from: now.roundUp(magnitude: .hours, calendar: testCal, stepSize: 2 * 60 * 60)!),
231231
"2022-08-09T00:00:00.000Z"
232232
)
233233

234234
XCTAssertEqual(
235-
formatter.string(from: now.round(magnitude: .hours, calendar: testCal, stepSize: 6 * 60 * 60)!),
235+
formatter.string(from: now.roundUp(magnitude: .hours, calendar: testCal, stepSize: 6 * 60 * 60)!),
236236
"2022-08-09T00:00:00.000Z"
237237
)
238238
}
@@ -243,21 +243,21 @@ final class DateNiceValueTests: XCTestCase {
243243
XCTAssertEqual(formatter.string(from: now), "2022-08-08T22:43:09.011Z")
244244

245245
XCTAssertEqual(
246-
formatter.string(from: now.round(magnitude: .days, calendar: testCal, stepSize: 1 * 24 * 60 * 60)!),
246+
formatter.string(from: now.roundUp(magnitude: .days, calendar: testCal, stepSize: 1 * 24 * 60 * 60)!),
247247
"2022-08-09T00:00:00.000Z"
248248
)
249249

250250
XCTAssertEqual(
251-
formatter.string(from: now.round(magnitude: .days, calendar: testCal, stepSize: 2 * 24 * 60 * 60)!),
251+
formatter.string(from: now.roundUp(magnitude: .days, calendar: testCal, stepSize: 2 * 24 * 60 * 60)!),
252252
"2022-08-10T00:00:00.000Z"
253253
)
254254

255255
// NOTE(heckj): This is rounding down to the 7th day of the month rather than to a specific "day of week"
256256
// and we might want to choose the other path in terms of "nice values" that are spanning 7 day (week)
257257
// increments.
258258
XCTAssertEqual(
259-
formatter.string(from: now.round(magnitude: .days, calendar: testCal, stepSize: 7 * 24 * 60 * 60)!),
260-
"2022-08-15T00:00:00.000Z"
259+
formatter.string(from: now.roundUp(magnitude: .days, calendar: testCal, stepSize: 7 * 24 * 60 * 60)!),
260+
"2022-08-14T00:00:00.000Z"
261261
)
262262
}
263263

@@ -267,18 +267,18 @@ final class DateNiceValueTests: XCTestCase {
267267
XCTAssertEqual(formatter.string(from: now), "2022-08-08T22:43:09.011Z")
268268

269269
XCTAssertEqual(
270-
formatter.string(from: now.round(magnitude: .months, calendar: testCal, stepSize: 1 * 28 * 24 * 60 * 60)!),
270+
formatter.string(from: now.roundUp(magnitude: .months, calendar: testCal, stepSize: 1 * 28 * 24 * 60 * 60)!),
271271
"2022-09-01T00:00:00.000Z"
272272
)
273273

274274
XCTAssertEqual(
275-
formatter.string(from: now.round(magnitude: .months, calendar: testCal, stepSize: 2 * 28 * 24 * 60 * 60)!),
276-
"2022-09-01T00:00:00.000Z"
275+
formatter.string(from: now.roundUp(magnitude: .months, calendar: testCal, stepSize: 2 * 28 * 24 * 60 * 60)!),
276+
"2022-10-01T00:00:00.000Z"
277277
)
278278

279279
XCTAssertEqual(
280-
formatter.string(from: now.round(magnitude: .months, calendar: testCal, stepSize: 6 * 28 * 24 * 60 * 60)!),
281-
"2022-12-01T00:00:00.000Z"
280+
formatter.string(from: now.roundUp(magnitude: .months, calendar: testCal, stepSize: 6 * 28 * 24 * 60 * 60)!),
281+
"2023-01-01T00:00:00.000Z"
282282
)
283283
}
284284

0 commit comments

Comments
 (0)