Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support forDate position between 2 dates range (positionInRange) #694

Merged
merged 8 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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