Skip to content

Commit

Permalink
Merge pull request #694 from RomanPodymov/develop
Browse files Browse the repository at this point in the history
Added support forDate position between 2 dates range (positionInRange)
  • Loading branch information
malcommac authored Sep 15, 2020
2 parents f60f0ac + 4559d55 commit 1aad319
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 19 deletions.
12 changes: 11 additions & 1 deletion Sources/SwiftDate/Date/Date+Compare.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ public extension Date {
return inDefaultRegion().isAfterDate(refDate.inDefaultRegion(), orEqual: orEqual, granularity: granularity)
}

/// Returns a value between 0.0 and 1.0 or nil, that is the position of current date between 2 other dates.
///
/// - Parameters:
/// - startDate: range upper bound date
/// - endDate: range lower bound date
/// - Returns: `nil` if current date is not between `startDate` and `endDate`. Otherwise returns position between `startDate` and `endDate`.
func positionInRange(date startDate: Date, and endDate: Date) -> Double? {
return inDefaultRegion().positionInRange(date: startDate.inDefaultRegion(), and: endDate.inDefaultRegion())
}

/// Return true if receiver date is contained in the range specified by two dates.
///
/// - Parameters:
Expand All @@ -79,7 +89,7 @@ public extension Date {
/// - granularity: smallest unit that must, along with all larger units, be greater for the given dates.
/// - Returns: Boolean
func isInRange(date startDate: Date, and endDate: Date, orEqual: Bool = false, granularity: Calendar.Component = .nanosecond) -> Bool {
return self.inDefaultRegion().isInRange(date: startDate.inDefaultRegion(), and: endDate.inDefaultRegion(), orEqual: orEqual, granularity: granularity)
return inDefaultRegion().isInRange(date: startDate.inDefaultRegion(), and: endDate.inDefaultRegion(), orEqual: orEqual, granularity: granularity)
}

/// Compares equality of two given dates based on their components down to a given unit
Expand Down
18 changes: 18 additions & 0 deletions Sources/SwiftDate/DateInRegion/DateInRegion+Compare.swift
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,24 @@ public extension DateInRegion {
return (compare(toDate: date, granularity: granularity) == .orderedSame)
}

/// Returns a value between 0.0 and 1.0 or nil, that is the position of current date between 2 other dates.
///
/// - Parameters:
/// - startDate: range upper bound date
/// - endDate: range lower bound date
/// - Returns: `nil` if current date is not between `startDate` and `endDate`. Otherwise returns position between `startDate` and `endDate`.
func positionInRange(date startDate: DateInRegion, and endDate: DateInRegion) -> Double? {
let diffCurrentDateAndStartDate = self - startDate
guard diffCurrentDateAndStartDate >= 0 else {
return nil
}
let diffEndDateAndStartDate = endDate - startDate
guard diffEndDateAndStartDate > 0, diffCurrentDateAndStartDate <= diffEndDateAndStartDate else {
return nil
}
return diffCurrentDateAndStartDate / diffEndDateAndStartDate
}

/// Return `true` if receiver data is contained in the range specified by two dates.
///
/// - Parameters:
Expand Down
57 changes: 39 additions & 18 deletions Tests/SwiftDateTests/TestDate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,51 @@
// Copyright © 2019 SwiftDate. All rights reserved.
//

import SwiftDate
import XCTest

class TestDate: XCTestCase {

override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testDifferencesBetweenDates() {
let date = Date()
let date2 = "2019-01-05".toDate()!.date
let result = date.differences(in: [.hour, .day, .month], from: date2)
print(result)
}
func testDifferencesBetweenDates() {
let date = Date()
let date2 = "2019-01-05".toDate()!.date
let result = date.differences(in: [.hour, .day, .month], from: date2)
print(result)
}

func testDifferenceBetweenDates() {
let date = Date()
let date2 = "2019-01-05".toDate()!.date
let result = date.difference(in: .day, from: date2)
print(result!)
}
func testDifferenceBetweenDates() {
let date = Date()
let date2 = "2019-01-05".toDate()!.date
let result = date.difference(in: .day, from: date2)
print(result!)
}

func testPositionInRange() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let regionLondon = Region(calendar: Calendars.gregorian, zone: Zones.europeLondon, locale: Locales.english)
let dateFormat = "yyyy-MM-dd HH:mm:ss"

let lowerBound = "2018-05-31 23:00:00".toDate(dateFormat, region: regionRome)!.date
let upperBound = "2018-06-01 01:00:00".toDate(dateFormat, region: regionRome)!.date

let testDate1 = "2018-06-01 00:30:00".toDate(dateFormat, region: regionRome)!.date
XCTAssertEqual( testDate1.positionInRange(date: lowerBound, and: upperBound), 0.75)

let testDate2 = "2018-05-31 22:30:00".toDate(dateFormat, region: regionLondon)!.date
XCTAssertEqual( testDate2.positionInRange(date: lowerBound, and: upperBound), 0.25)

let testDate3 = "2018-05-31 21:00:00".toDate(dateFormat, region: regionLondon)!.date
XCTAssertNil( testDate3.positionInRange(date: lowerBound, and: upperBound))

let testDate4 = "2018-06-01 03:00:00".toDate(dateFormat, region: regionLondon)!.date
XCTAssertNil( testDate4.positionInRange(date: lowerBound, and: upperBound))
}
}
21 changes: 21 additions & 0 deletions Tests/SwiftDateTests/TestDateInRegion+Compare.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,27 @@ class TestDateInRegion_Compare: XCTestCase {
XCTAssert( date2.isAfterDate(date1, granularity: .year) == false, "Failed to isAfterDate() - .year == false")
}

func testDateInRegion_positionInRange() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let regionLondon = Region(calendar: Calendars.gregorian, zone: Zones.europeLondon, locale: Locales.english)
let dateFormat = "yyyy-MM-dd HH:mm:ss"

let lowerBound = DateInRegion("2018-05-31 23:00:00", format: dateFormat, region: regionRome)!
let upperBound = DateInRegion("2018-06-01 01:00:00", format: dateFormat, region: regionRome)!

let testDate1 = DateInRegion("2018-06-01 00:30:00", format: dateFormat, region: regionRome)!
XCTAssertEqual( testDate1.positionInRange(date: lowerBound, and: upperBound), 0.75)

let testDate2 = DateInRegion("2018-05-31 22:30:00", format: dateFormat, region: regionLondon)!
XCTAssertEqual( testDate2.positionInRange(date: lowerBound, and: upperBound), 0.25)

let testDate3 = DateInRegion("2018-05-31 21:00:00", format: dateFormat, region: regionLondon)!
XCTAssertNil( testDate3.positionInRange(date: lowerBound, and: upperBound))

let testDate4 = DateInRegion("2018-06-01 03:00:00", format: dateFormat, region: regionLondon)!
XCTAssertNil( testDate4.positionInRange(date: lowerBound, and: upperBound))
}

func testDateInRegion_isInRange() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let regionLondon = Region(calendar: Calendars.gregorian, zone: Zones.europeLondon, locale: Locales.english)
Expand Down

0 comments on commit 1aad319

Please sign in to comment.