|
|
@ -16,29 +16,27 @@ import Foundation |
|
|
|
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information. |
|
|
|
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public protocol TimePeriodProtocol { |
|
|
|
public protocol TimePeriodProtocol { |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Variables |
|
|
|
// MARK: - Variables |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The start date for a TimePeriod representing the starting boundary of the time period |
|
|
|
* The start date for a TimePeriod representing the starting boundary of the time period |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var beginning: Date? {get set} |
|
|
|
var beginning: Date? { get set } |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The end date for a TimePeriod representing the ending boundary of the time period |
|
|
|
* The end date for a TimePeriod representing the ending boundary of the time period |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var end: Date? {get set} |
|
|
|
var end: Date? { get set } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public extension TimePeriodProtocol { |
|
|
|
public extension TimePeriodProtocol { |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Information |
|
|
|
// MARK: - Information |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* True if the `TimePeriod`'s duration is zero |
|
|
|
* True if the `TimePeriod`'s duration is zero |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var isMoment: Bool { |
|
|
|
var isMoment: Bool { |
|
|
|
return self.beginning == self.end |
|
|
|
return beginning == end |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -46,8 +44,8 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var years: Int { |
|
|
|
var years: Int { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return self.beginning!.yearsEarlier(than: self.end!) |
|
|
|
return beginning!.yearsEarlier(than: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return Int.max |
|
|
|
return Int.max |
|
|
|
} |
|
|
|
} |
|
|
@ -57,8 +55,8 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var weeks: Int { |
|
|
|
var weeks: Int { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return self.beginning!.weeksEarlier(than: self.end!) |
|
|
|
return beginning!.weeksEarlier(than: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return Int.max |
|
|
|
return Int.max |
|
|
|
} |
|
|
|
} |
|
|
@ -68,8 +66,8 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var days: Int { |
|
|
|
var days: Int { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return self.beginning!.daysEarlier(than: self.end!) |
|
|
|
return beginning!.daysEarlier(than: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return Int.max |
|
|
|
return Int.max |
|
|
|
} |
|
|
|
} |
|
|
@ -79,8 +77,8 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var hours: Int { |
|
|
|
var hours: Int { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return self.beginning!.hoursEarlier(than: self.end!) |
|
|
|
return beginning!.hoursEarlier(than: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return Int.max |
|
|
|
return Int.max |
|
|
|
} |
|
|
|
} |
|
|
@ -90,8 +88,8 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var minutes: Int { |
|
|
|
var minutes: Int { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return self.beginning!.minutesEarlier(than: self.end!) |
|
|
|
return beginning!.minutesEarlier(than: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return Int.max |
|
|
|
return Int.max |
|
|
|
} |
|
|
|
} |
|
|
@ -101,8 +99,8 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
* Returns the max int if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var seconds: Int { |
|
|
|
var seconds: Int { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return self.beginning!.secondsEarlier(than: self.end!) |
|
|
|
return beginning!.secondsEarlier(than: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return Int.max |
|
|
|
return Int.max |
|
|
|
} |
|
|
|
} |
|
|
@ -112,7 +110,7 @@ public extension TimePeriodProtocol { |
|
|
|
* Returns a time chunk with all zeroes if beginning or end are nil. |
|
|
|
* Returns a time chunk with all zeroes if beginning or end are nil. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var chunk: TimeChunk { |
|
|
|
var chunk: TimeChunk { |
|
|
|
if beginning != nil && end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return beginning!.chunkBetween(date: end!) |
|
|
|
return beginning!.chunkBetween(date: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) |
|
|
|
return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) |
|
|
@ -123,8 +121,8 @@ public extension TimePeriodProtocol { |
|
|
|
* `TimePeriod` as a `TimeInterval`. |
|
|
|
* `TimePeriod` as a `TimeInterval`. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var duration: TimeInterval { |
|
|
|
var duration: TimeInterval { |
|
|
|
if self.beginning != nil && self.end != nil { |
|
|
|
if beginning != nil, end != nil { |
|
|
|
return abs(self.beginning!.timeIntervalSince(self.end!)) |
|
|
|
return abs(beginning!.timeIntervalSince(end!)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return TimeInterval(Double.greatestFiniteMagnitude) |
|
|
|
return TimeInterval(Double.greatestFiniteMagnitude) |
|
|
@ -144,37 +142,36 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: The relationship between self and the given time period |
|
|
|
* - returns: The relationship between self and the given time period |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func relation(to period: TimePeriodProtocol) -> Relation { |
|
|
|
func relation(to period: TimePeriodProtocol) -> Relation { |
|
|
|
//Make sure that all start and end points exist for comparison |
|
|
|
// Make sure that all start and end points exist for comparison |
|
|
|
if (self.beginning != nil && self.end != nil && period.beginning != nil && period.end != nil) { |
|
|
|
if beginning != nil, end != nil, period.beginning != nil, period.end != nil { |
|
|
|
//Make sure time periods are of positive durations |
|
|
|
// Make sure time periods are of positive durations |
|
|
|
if (self.beginning!.isEarlier(than: self.end!) && period.beginning!.isEarlier(than: period.end!)) { |
|
|
|
if beginning!.isEarlier(than: end!), period.beginning!.isEarlier(than: period.end!) { |
|
|
|
|
|
|
|
// Make comparisons |
|
|
|
//Make comparisons |
|
|
|
if period.end!.isEarlier(than: beginning!) { |
|
|
|
if (period.end!.isEarlier(than: self.beginning!)) { |
|
|
|
|
|
|
|
return .after |
|
|
|
return .after |
|
|
|
} else if (period.end!.equals(self.beginning!)) { |
|
|
|
} else if period.end!.equals(beginning!) { |
|
|
|
return .startTouching |
|
|
|
return .startTouching |
|
|
|
} else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isEarlier(than: self.end!)) { |
|
|
|
} else if period.beginning!.isEarlier(than: beginning!), period.end!.isEarlier(than: end!) { |
|
|
|
return .startInside |
|
|
|
return .startInside |
|
|
|
} else if (period.beginning!.equals(self.beginning!) && period.end!.isLater(than: self.end!)) { |
|
|
|
} else if period.beginning!.equals(beginning!), period.end!.isLater(than: end!) { |
|
|
|
return .insideStartTouching |
|
|
|
return .insideStartTouching |
|
|
|
} else if (period.beginning!.equals(self.beginning!) && period.end!.isEarlier(than: self.end!)) { |
|
|
|
} else if period.beginning!.equals(beginning!), period.end!.isEarlier(than: end!) { |
|
|
|
return .enclosingStartTouching |
|
|
|
return .enclosingStartTouching |
|
|
|
} else if (period.beginning!.isLater(than: self.beginning!) && period.end!.isEarlier(than: self.end!)) { |
|
|
|
} else if period.beginning!.isLater(than: beginning!), period.end!.isEarlier(than: end!) { |
|
|
|
return .enclosing |
|
|
|
return .enclosing |
|
|
|
} else if (period.beginning!.isLater(than: self.beginning!) && period.end!.equals(self.end!)) { |
|
|
|
} else if period.beginning!.isLater(than: beginning!), period.end!.equals(end!) { |
|
|
|
return .enclosingEndTouching |
|
|
|
return .enclosingEndTouching |
|
|
|
} else if (period.beginning!.equals(self.beginning!) && period.end!.equals(self.end!)) { |
|
|
|
} else if period.beginning!.equals(beginning!), period.end!.equals(end!) { |
|
|
|
return .exactMatch |
|
|
|
return .exactMatch |
|
|
|
} else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.end!)) { |
|
|
|
} else if period.beginning!.isEarlier(than: beginning!), period.end!.isLater(than: end!) { |
|
|
|
return .inside |
|
|
|
return .inside |
|
|
|
} else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.equals(self.end!)) { |
|
|
|
} else if period.beginning!.isEarlier(than: beginning!), period.end!.equals(end!) { |
|
|
|
return .insideEndTouching |
|
|
|
return .insideEndTouching |
|
|
|
} else if (period.beginning!.isEarlier(than: self.end!) && period.end!.isLater(than: self.end!)) { |
|
|
|
} else if period.beginning!.isEarlier(than: end!), period.end!.isLater(than: end!) { |
|
|
|
return .endInside |
|
|
|
return .endInside |
|
|
|
} else if (period.beginning!.equals(self.end!) && period.end!.isLater(than: self.end!)) { |
|
|
|
} else if period.beginning!.equals(end!), period.end!.isLater(than: end!) { |
|
|
|
return .endTouching |
|
|
|
return .endTouching |
|
|
|
} else if (period.beginning!.isLater(than: self.end!)) { |
|
|
|
} else if period.beginning!.isLater(than: end!) { |
|
|
|
return .before |
|
|
|
return .before |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -192,7 +189,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if the periods are the same |
|
|
|
* - returns: True if the periods are the same |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func equals(_ period: TimePeriodProtocol) -> Bool { |
|
|
|
func equals(_ period: TimePeriodProtocol) -> Bool { |
|
|
|
return self.beginning == period.beginning && self.end == period.end |
|
|
|
return beginning == period.beginning && end == period.end |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -204,7 +201,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if self is inside of the given `TimePeriod` |
|
|
|
* - returns: True if self is inside of the given `TimePeriod` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func isInside(of period: TimePeriodProtocol) -> Bool { |
|
|
|
func isInside(of period: TimePeriodProtocol) -> Bool { |
|
|
|
return period.beginning!.isEarlierThanOrEqual(to: self.beginning!) && period.end!.isLaterThanOrEqual(to: self.end!) |
|
|
|
return period.beginning!.isEarlierThanOrEqual(to: beginning!) && period.end!.isLaterThanOrEqual(to: end!) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -216,10 +213,10 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if the given `TimePeriod` is inside of self |
|
|
|
* - returns: True if the given `TimePeriod` is inside of self |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func contains(_ date: Date, interval: Interval) -> Bool { |
|
|
|
func contains(_ date: Date, interval: Interval) -> Bool { |
|
|
|
if (interval == .open) { |
|
|
|
if interval == .open { |
|
|
|
return self.beginning!.isEarlier(than: date) && self.end!.isLater(than: date) |
|
|
|
return beginning!.isEarlier(than: date) && end!.isLater(than: date) |
|
|
|
} else if (interval == .closed) { |
|
|
|
} else if interval == .closed { |
|
|
|
return (self.beginning!.isEarlierThanOrEqual(to: date) && self.end!.isLaterThanOrEqual(to: date)) |
|
|
|
return (beginning!.isEarlierThanOrEqual(to: date) && end!.isLaterThanOrEqual(to: date)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false |
|
|
|
return false |
|
|
@ -234,7 +231,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if the given `TimePeriod` is inside of self |
|
|
|
* - returns: True if the given `TimePeriod` is inside of self |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func contains(_ period: TimePeriodProtocol) -> Bool { |
|
|
|
func contains(_ period: TimePeriodProtocol) -> Bool { |
|
|
|
return self.beginning!.isEarlierThanOrEqual(to: period.beginning!) && self.end!.isLaterThanOrEqual(to: period.end!) |
|
|
|
return beginning!.isEarlierThanOrEqual(to: period.beginning!) && end!.isLaterThanOrEqual(to: period.end!) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -245,16 +242,16 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if there is a period of time that is shared by both `TimePeriod`s |
|
|
|
* - returns: True if there is a period of time that is shared by both `TimePeriod`s |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func overlaps(with period: TimePeriodProtocol) -> Bool { |
|
|
|
func overlaps(with period: TimePeriodProtocol) -> Bool { |
|
|
|
//Outside -> Inside |
|
|
|
// Outside -> Inside |
|
|
|
if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.beginning!)) { |
|
|
|
if period.beginning!.isEarlier(than: beginning!), period.end!.isLater(than: beginning!) { |
|
|
|
return true |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
//Enclosing |
|
|
|
// Enclosing |
|
|
|
else if (period.beginning!.isLaterThanOrEqual(to: self.beginning!) && period.end!.isEarlierThanOrEqual(to: self.end!)) { |
|
|
|
else if period.beginning!.isLaterThanOrEqual(to: beginning!), period.end!.isEarlierThanOrEqual(to: end!) { |
|
|
|
return true |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
//Inside -> Out |
|
|
|
// Inside -> Out |
|
|
|
else if(period.beginning!.isEarlier(than: self.end!) && period.end!.isLater(than: self.end!)) { |
|
|
|
else if period.beginning!.isEarlier(than: end!), period.end!.isLater(than: end!) { |
|
|
|
return true |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
return false |
|
|
|
return false |
|
|
@ -268,7 +265,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if there is a period of time or moment that is shared by both `TimePeriod`s |
|
|
|
* - returns: True if there is a period of time or moment that is shared by both `TimePeriod`s |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func intersects(with period: TimePeriodProtocol) -> Bool { |
|
|
|
func intersects(with period: TimePeriodProtocol) -> Bool { |
|
|
|
return self.relation(to: period) != .after && self.relation(to: period) != .before |
|
|
|
return relation(to: period) != .after && relation(to: period) != .before |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -279,7 +276,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if there is a period of time between self and the given `TimePeriod` not contained by either period |
|
|
|
* - returns: True if there is a period of time between self and the given `TimePeriod` not contained by either period |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func hasGap(between period: TimePeriodProtocol) -> Bool { |
|
|
|
func hasGap(between period: TimePeriodProtocol) -> Bool { |
|
|
|
return self.isBefore(period: period) || self.isAfter(period: period) |
|
|
|
return isBefore(period: period) || isAfter(period: period) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -290,10 +287,10 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: The gap between the periods. Zero if there is no gap. |
|
|
|
* - returns: The gap between the periods. Zero if there is no gap. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func gap(between period: TimePeriodProtocol) -> TimeInterval { |
|
|
|
func gap(between period: TimePeriodProtocol) -> TimeInterval { |
|
|
|
if (self.end!.isEarlier(than: period.beginning!)) { |
|
|
|
if end!.isEarlier(than: period.beginning!) { |
|
|
|
return abs(self.end!.timeIntervalSince(period.beginning!)) |
|
|
|
return abs(end!.timeIntervalSince(period.beginning!)) |
|
|
|
} else if (period.end!.isEarlier(than: self.beginning!)) { |
|
|
|
} else if period.end!.isEarlier(than: beginning!) { |
|
|
|
return abs(period.end!.timeIntervalSince(self.beginning!)) |
|
|
|
return abs(period.end!.timeIntervalSince(beginning!)) |
|
|
|
} |
|
|
|
} |
|
|
|
return 0 |
|
|
|
return 0 |
|
|
|
} |
|
|
|
} |
|
|
@ -307,8 +304,8 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: The gap between the periods, zero if there is no gap |
|
|
|
* - returns: The gap between the periods, zero if there is no gap |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func gap(between period: TimePeriodProtocol) -> TimeChunk? { |
|
|
|
func gap(between period: TimePeriodProtocol) -> TimeChunk? { |
|
|
|
if self.end != nil && period.beginning != nil { |
|
|
|
if end != nil, period.beginning != nil { |
|
|
|
return (self.end?.chunkBetween(date: period.beginning!))! |
|
|
|
return (end?.chunkBetween(date: period.beginning!))! |
|
|
|
} |
|
|
|
} |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
@ -321,7 +318,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if self is after the given `TimePeriod` |
|
|
|
* - returns: True if self is after the given `TimePeriod` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func isAfter(period: TimePeriodProtocol) -> Bool { |
|
|
|
func isAfter(period: TimePeriodProtocol) -> Bool { |
|
|
|
return self.relation(to: period) == .after |
|
|
|
return relation(to: period) == .after |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -332,7 +329,7 @@ public extension TimePeriodProtocol { |
|
|
|
* - returns: True if self is after the given `TimePeriod` |
|
|
|
* - returns: True if self is after the given `TimePeriod` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func isBefore(period: TimePeriodProtocol) -> Bool { |
|
|
|
func isBefore(period: TimePeriodProtocol) -> Bool { |
|
|
|
return self.relation(to: period) == .before |
|
|
|
return relation(to: period) == .before |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Shifts |
|
|
|
// MARK: - Shifts |
|
|
@ -345,8 +342,8 @@ public extension TimePeriodProtocol { |
|
|
|
* - parameter timeInterval: The time interval to shift the period by |
|
|
|
* - parameter timeInterval: The time interval to shift the period by |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
mutating func shift(by timeInterval: TimeInterval) { |
|
|
|
mutating func shift(by timeInterval: TimeInterval) { |
|
|
|
self.beginning?.addTimeInterval(timeInterval) |
|
|
|
beginning?.addTimeInterval(timeInterval) |
|
|
|
self.end?.addTimeInterval(timeInterval) |
|
|
|
end?.addTimeInterval(timeInterval) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -355,8 +352,8 @@ public extension TimePeriodProtocol { |
|
|
|
* - parameter chunk: The time chunk to shift the period by |
|
|
|
* - parameter chunk: The time chunk to shift the period by |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
mutating func shift(by chunk: TimeChunk) { |
|
|
|
mutating func shift(by chunk: TimeChunk) { |
|
|
|
self.beginning = self.beginning?.add(chunk) |
|
|
|
beginning = beginning?.add(chunk) |
|
|
|
self.end = self.end?.add(chunk) |
|
|
|
end = end?.add(chunk) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Lengthen / Shorten |
|
|
|
// MARK: - Lengthen / Shorten |
|
|
@ -372,12 +369,12 @@ public extension TimePeriodProtocol { |
|
|
|
mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) { |
|
|
|
mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) { |
|
|
|
switch anchor { |
|
|
|
switch anchor { |
|
|
|
case .beginning: |
|
|
|
case .beginning: |
|
|
|
self.end = self.end?.addingTimeInterval(timeInterval) |
|
|
|
end = end?.addingTimeInterval(timeInterval) |
|
|
|
case .center: |
|
|
|
case .center: |
|
|
|
self.beginning = self.beginning?.addingTimeInterval(-timeInterval/2.0) |
|
|
|
beginning = beginning?.addingTimeInterval(-timeInterval / 2.0) |
|
|
|
self.end = self.end?.addingTimeInterval(timeInterval/2.0) |
|
|
|
end = end?.addingTimeInterval(timeInterval / 2.0) |
|
|
|
case .end: |
|
|
|
case .end: |
|
|
|
self.beginning = self.beginning?.addingTimeInterval(-timeInterval) |
|
|
|
beginning = beginning?.addingTimeInterval(-timeInterval) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -390,12 +387,12 @@ public extension TimePeriodProtocol { |
|
|
|
mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) { |
|
|
|
mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) { |
|
|
|
switch anchor { |
|
|
|
switch anchor { |
|
|
|
case .beginning: |
|
|
|
case .beginning: |
|
|
|
self.end = self.end?.add(chunk) |
|
|
|
end = end?.add(chunk) |
|
|
|
case .center: |
|
|
|
case .center: |
|
|
|
// Do not lengthen by TimeChunk at center |
|
|
|
// Do not lengthen by TimeChunk at center |
|
|
|
print("Mutation via chunk from center anchor is not supported.") |
|
|
|
print("Mutation via chunk from center anchor is not supported.") |
|
|
|
case .end: |
|
|
|
case .end: |
|
|
|
self.beginning = self.beginning?.subtract(chunk) |
|
|
|
beginning = beginning?.subtract(chunk) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -408,12 +405,12 @@ public extension TimePeriodProtocol { |
|
|
|
mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) { |
|
|
|
mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) { |
|
|
|
switch anchor { |
|
|
|
switch anchor { |
|
|
|
case .beginning: |
|
|
|
case .beginning: |
|
|
|
self.end = self.end?.addingTimeInterval(-timeInterval) |
|
|
|
end = end?.addingTimeInterval(-timeInterval) |
|
|
|
case .center: |
|
|
|
case .center: |
|
|
|
self.beginning = self.beginning?.addingTimeInterval(timeInterval/2.0) |
|
|
|
beginning = beginning?.addingTimeInterval(timeInterval / 2.0) |
|
|
|
self.end = self.end?.addingTimeInterval(-timeInterval/2.0) |
|
|
|
end = end?.addingTimeInterval(-timeInterval / 2.0) |
|
|
|
case .end: |
|
|
|
case .end: |
|
|
|
self.beginning = self.beginning?.addingTimeInterval(timeInterval) |
|
|
|
beginning = beginning?.addingTimeInterval(timeInterval) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -426,12 +423,12 @@ public extension TimePeriodProtocol { |
|
|
|
mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) { |
|
|
|
mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) { |
|
|
|
switch anchor { |
|
|
|
switch anchor { |
|
|
|
case .beginning: |
|
|
|
case .beginning: |
|
|
|
self.end = self.end?.subtract(chunk) |
|
|
|
end = end?.subtract(chunk) |
|
|
|
case .center: |
|
|
|
case .center: |
|
|
|
// Do not shorten by TimeChunk at center |
|
|
|
// Do not shorten by TimeChunk at center |
|
|
|
print("Mutation via chunk from center anchor is not supported.") |
|
|
|
print("Mutation via chunk from center anchor is not supported.") |
|
|
|
case .end: |
|
|
|
case .end: |
|
|
|
self.beginning = self.beginning?.add(chunk) |
|
|
|
beginning = beginning?.add(chunk) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -444,8 +441,8 @@ public extension TimePeriodProtocol { |
|
|
|
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information. |
|
|
|
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
open class TimePeriod: TimePeriodProtocol { |
|
|
|
open class TimePeriod: TimePeriodProtocol { |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Variables |
|
|
|
// MARK: - Variables |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The start date for a TimePeriod representing the starting boundary of the time period |
|
|
|
* The start date for a TimePeriod representing the starting boundary of the time period |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -458,9 +455,7 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Initializers |
|
|
|
// MARK: - Initializers |
|
|
|
|
|
|
|
|
|
|
|
init() { |
|
|
|
init() {} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init(beginning: Date?, end: Date?) { |
|
|
|
init(beginning: Date?, end: Date?) { |
|
|
|
self.beginning = beginning |
|
|
|
self.beginning = beginning |
|
|
@ -469,27 +464,27 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
|
|
|
|
|
|
|
|
init(beginning: Date, duration: TimeInterval) { |
|
|
|
init(beginning: Date, duration: TimeInterval) { |
|
|
|
self.beginning = beginning |
|
|
|
self.beginning = beginning |
|
|
|
self.end = beginning + duration |
|
|
|
end = beginning + duration |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
init(end: Date, duration: TimeInterval) { |
|
|
|
init(end: Date, duration: TimeInterval) { |
|
|
|
self.end = end |
|
|
|
self.end = end |
|
|
|
self.beginning = end.addingTimeInterval(-duration) |
|
|
|
beginning = end.addingTimeInterval(-duration) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
init(beginning: Date, chunk: TimeChunk) { |
|
|
|
init(beginning: Date, chunk: TimeChunk) { |
|
|
|
self.beginning = beginning |
|
|
|
self.beginning = beginning |
|
|
|
self.end = beginning + chunk |
|
|
|
end = beginning + chunk |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
init(end: Date, chunk: TimeChunk) { |
|
|
|
init(end: Date, chunk: TimeChunk) { |
|
|
|
self.end = end |
|
|
|
self.end = end |
|
|
|
self.beginning = end - chunk |
|
|
|
beginning = end - chunk |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
init(chunk: TimeChunk) { |
|
|
|
init(chunk: TimeChunk) { |
|
|
|
self.beginning = Date() |
|
|
|
beginning = Date() |
|
|
|
self.end = self.beginning?.add(chunk) |
|
|
|
end = beginning?.add(chunk) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Shifted |
|
|
|
// MARK: - Shifted |
|
|
@ -503,8 +498,8 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func shifted(by timeInterval: TimeInterval) -> TimePeriod { |
|
|
|
func shifted(by timeInterval: TimeInterval) -> TimePeriod { |
|
|
|
let timePeriod = TimePeriod() |
|
|
|
let timePeriod = TimePeriod() |
|
|
|
timePeriod.beginning = self.beginning?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.end = self.end?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.end = end?.addingTimeInterval(timeInterval) |
|
|
|
return timePeriod |
|
|
|
return timePeriod |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -517,8 +512,8 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
func shifted(by chunk: TimeChunk) -> TimePeriod { |
|
|
|
func shifted(by chunk: TimeChunk) -> TimePeriod { |
|
|
|
let timePeriod = TimePeriod() |
|
|
|
let timePeriod = TimePeriod() |
|
|
|
timePeriod.beginning = self.beginning?.add(chunk) |
|
|
|
timePeriod.beginning = beginning?.add(chunk) |
|
|
|
timePeriod.end = self.end?.add(chunk) |
|
|
|
timePeriod.end = end?.add(chunk) |
|
|
|
return timePeriod |
|
|
|
return timePeriod |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -538,14 +533,14 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
let timePeriod = TimePeriod() |
|
|
|
let timePeriod = TimePeriod() |
|
|
|
switch anchor { |
|
|
|
switch anchor { |
|
|
|
case .beginning: |
|
|
|
case .beginning: |
|
|
|
timePeriod.beginning = self.beginning |
|
|
|
timePeriod.beginning = beginning |
|
|
|
timePeriod.end = self.end?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.end = end?.addingTimeInterval(timeInterval) |
|
|
|
case .center: |
|
|
|
case .center: |
|
|
|
timePeriod.beginning = self.beginning?.addingTimeInterval(-timeInterval) |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval) |
|
|
|
timePeriod.end = self.end?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.end = end?.addingTimeInterval(timeInterval) |
|
|
|
case .end: |
|
|
|
case .end: |
|
|
|
timePeriod.beginning = self.beginning?.addingTimeInterval(-timeInterval) |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval) |
|
|
|
timePeriod.end = self.end |
|
|
|
timePeriod.end = end |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return timePeriod |
|
|
|
return timePeriod |
|
|
@ -590,8 +585,8 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
timePeriod.beginning = beginning |
|
|
|
timePeriod.beginning = beginning |
|
|
|
timePeriod.end = end?.addingTimeInterval(-timeInterval) |
|
|
|
timePeriod.end = end?.addingTimeInterval(-timeInterval) |
|
|
|
case .center: |
|
|
|
case .center: |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval/2) |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval / 2) |
|
|
|
timePeriod.end = end?.addingTimeInterval(timeInterval/2) |
|
|
|
timePeriod.end = end?.addingTimeInterval(timeInterval / 2) |
|
|
|
case .end: |
|
|
|
case .end: |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.beginning = beginning?.addingTimeInterval(timeInterval) |
|
|
|
timePeriod.end = end |
|
|
|
timePeriod.end = end |
|
|
@ -629,7 +624,7 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Operator overload for checking if two `TimePeriod`s are equal |
|
|
|
* Operator overload for checking if two `TimePeriod`s are equal |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static func ==(leftAddend: TimePeriod, rightAddend: TimePeriod) -> Bool { |
|
|
|
static func == (leftAddend: TimePeriod, rightAddend: TimePeriod) -> Bool { |
|
|
|
return leftAddend.equals(rightAddend) |
|
|
|
return leftAddend.equals(rightAddend) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -637,14 +632,14 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Operator overload for lengthening a `TimePeriod` by a `TimeInterval` |
|
|
|
* Operator overload for lengthening a `TimePeriod` by a `TimeInterval` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static func +(leftAddend: TimePeriod, rightAddend: TimeInterval) -> TimePeriod { |
|
|
|
static func + (leftAddend: TimePeriod, rightAddend: TimeInterval) -> TimePeriod { |
|
|
|
return leftAddend.lengthened(by: rightAddend, at: .beginning) |
|
|
|
return leftAddend.lengthened(by: rightAddend, at: .beginning) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Operator overload for lengthening a `TimePeriod` by a `TimeChunk` |
|
|
|
* Operator overload for lengthening a `TimePeriod` by a `TimeChunk` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static func +(leftAddend: TimePeriod, rightAddend: TimeChunk) -> TimePeriod { |
|
|
|
static func + (leftAddend: TimePeriod, rightAddend: TimeChunk) -> TimePeriod { |
|
|
|
return leftAddend.lengthened(by: rightAddend, at: .beginning) |
|
|
|
return leftAddend.lengthened(by: rightAddend, at: .beginning) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -652,21 +647,21 @@ open class TimePeriod: TimePeriodProtocol { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Operator overload for shortening a `TimePeriod` by a `TimeInterval` |
|
|
|
* Operator overload for shortening a `TimePeriod` by a `TimeInterval` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static func -(minuend: TimePeriod, subtrahend: TimeInterval) -> TimePeriod { |
|
|
|
static func - (minuend: TimePeriod, subtrahend: TimeInterval) -> TimePeriod { |
|
|
|
return minuend.shortened(by: subtrahend, at: .beginning) |
|
|
|
return minuend.shortened(by: subtrahend, at: .beginning) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Operator overload for shortening a `TimePeriod` by a `TimeChunk` |
|
|
|
* Operator overload for shortening a `TimePeriod` by a `TimeChunk` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static func -(minuend: TimePeriod, subtrahend: TimeChunk) -> TimePeriod { |
|
|
|
static func - (minuend: TimePeriod, subtrahend: TimeChunk) -> TimePeriod { |
|
|
|
return minuend.shortened(by: subtrahend, at: .beginning) |
|
|
|
return minuend.shortened(by: subtrahend, at: .beginning) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Operator overload for checking if a `TimePeriod` is equal to a `TimePeriodProtocol` |
|
|
|
* Operator overload for checking if a `TimePeriod` is equal to a `TimePeriodProtocol` |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static func ==(left: TimePeriod, right: TimePeriodProtocol) -> Bool { |
|
|
|
static func == (left: TimePeriod, right: TimePeriodProtocol) -> Bool { |
|
|
|
return left.equals(right) |
|
|
|
return left.equals(right) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|