Browse Source

Remove unused classes.

pull/113/head
Abhishek Banthia 3 years ago
parent
commit
c1b3d7441d
  1. 16
      Clocker/Clocker.xcodeproj/project.pbxproj
  2. 667
      Clocker/Dependencies/Date Additions/TimePeriod.swift
  3. 177
      Clocker/Dependencies/Date Additions/TimePeriodChain.swift
  4. 267
      Clocker/Dependencies/Date Additions/TimePeriodCollection.swift
  5. 146
      Clocker/Dependencies/Date Additions/TimePeriodGroup.swift

16
Clocker/Clocker.xcodeproj/project.pbxproj

@ -71,11 +71,8 @@
35C36EF822595F14002FA5C6 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 35C36EEF22595F14002FA5C6 /* Onboarding.storyboard */; };
35C36EF922595F14002FA5C6 /* OnboardingParentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EF022595F14002FA5C6 /* OnboardingParentViewController.swift */; };
35C36EFB2259616B002FA5C6 /* Solar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EFA2259616B002FA5C6 /* Solar.swift */; };
35C36F0D225961DA002FA5C6 /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EFD225961D9002FA5C6 /* TimePeriod.swift */; };
35C36F0E225961DA002FA5C6 /* Date+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EFE225961D9002FA5C6 /* Date+Bundle.swift */; };
35C36F0F225961DA002FA5C6 /* TimePeriodCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36EFF225961D9002FA5C6 /* TimePeriodCollection.swift */; };
35C36F10225961DA002FA5C6 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F00225961D9002FA5C6 /* Constants.swift */; };
35C36F11225961DA002FA5C6 /* TimePeriodGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F01225961D9002FA5C6 /* TimePeriodGroup.swift */; };
35C36F12225961DA002FA5C6 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F02225961DA002FA5C6 /* Date+Components.swift */; };
35C36F13225961DA002FA5C6 /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F03225961DA002FA5C6 /* Date+TimeAgo.swift */; };
35C36F14225961DA002FA5C6 /* Integer+DateTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F04225961DA002FA5C6 /* Integer+DateTools.swift */; };
@ -86,7 +83,6 @@
35C36F19225961DA002FA5C6 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F09225961DA002FA5C6 /* Enums.swift */; };
35C36F1A225961DA002FA5C6 /* Date+Manipulations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F0A225961DA002FA5C6 /* Date+Manipulations.swift */; };
35C36F1B225961DA002FA5C6 /* Date+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F0B225961DA002FA5C6 /* Date+Format.swift */; };
35C36F1C225961DA002FA5C6 /* TimePeriodChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F0C225961DA002FA5C6 /* TimePeriodChain.swift */; };
35C36F2022596253002FA5C6 /* OneWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F1E22596253002FA5C6 /* OneWindowController.swift */; };
35C36F2122596253002FA5C6 /* AppearanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F1F22596253002FA5C6 /* AppearanceViewController.swift */; };
35C36F2B2259D6FA002FA5C6 /* ParentPanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F272259D6FA002FA5C6 /* ParentPanelController.swift */; };
@ -313,11 +309,8 @@
35C36EEF22595F14002FA5C6 /* Onboarding.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Onboarding.storyboard; sourceTree = "<group>"; };
35C36EF022595F14002FA5C6 /* OnboardingParentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingParentViewController.swift; sourceTree = "<group>"; };
35C36EFA2259616B002FA5C6 /* Solar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Solar.swift; sourceTree = "<group>"; };
35C36EFD225961D9002FA5C6 /* TimePeriod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriod.swift; sourceTree = "<group>"; };
35C36EFE225961D9002FA5C6 /* Date+Bundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Bundle.swift"; sourceTree = "<group>"; };
35C36EFF225961D9002FA5C6 /* TimePeriodCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodCollection.swift; sourceTree = "<group>"; };
35C36F00225961D9002FA5C6 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
35C36F01225961D9002FA5C6 /* TimePeriodGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodGroup.swift; sourceTree = "<group>"; };
35C36F02225961DA002FA5C6 /* Date+Components.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Components.swift"; sourceTree = "<group>"; };
35C36F03225961DA002FA5C6 /* Date+TimeAgo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+TimeAgo.swift"; sourceTree = "<group>"; };
35C36F04225961DA002FA5C6 /* Integer+DateTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Integer+DateTools.swift"; sourceTree = "<group>"; };
@ -328,7 +321,6 @@
35C36F09225961DA002FA5C6 /* Enums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = "<group>"; };
35C36F0A225961DA002FA5C6 /* Date+Manipulations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Manipulations.swift"; sourceTree = "<group>"; };
35C36F0B225961DA002FA5C6 /* Date+Format.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Format.swift"; sourceTree = "<group>"; };
35C36F0C225961DA002FA5C6 /* TimePeriodChain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodChain.swift; sourceTree = "<group>"; };
35C36F1E22596253002FA5C6 /* OneWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OneWindowController.swift; sourceTree = "<group>"; };
35C36F1F22596253002FA5C6 /* AppearanceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearanceViewController.swift; sourceTree = "<group>"; };
35C36F272259D6FA002FA5C6 /* ParentPanelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParentPanelController.swift; sourceTree = "<group>"; };
@ -600,10 +592,6 @@
35C36F09225961DA002FA5C6 /* Enums.swift */,
35C36F04225961DA002FA5C6 /* Integer+DateTools.swift */,
35C36F05225961DA002FA5C6 /* TimeChunk.swift */,
35C36EFD225961D9002FA5C6 /* TimePeriod.swift */,
35C36F0C225961DA002FA5C6 /* TimePeriodChain.swift */,
35C36EFF225961D9002FA5C6 /* TimePeriodCollection.swift */,
35C36F01225961D9002FA5C6 /* TimePeriodGroup.swift */,
);
path = "Date Additions";
sourceTree = "<group>";
@ -1358,7 +1346,6 @@
35C36F712259E185002FA5C6 /* NoTimezoneView.swift in Sources */,
35C36F2B2259D6FA002FA5C6 /* ParentPanelController.swift in Sources */,
35C36F582259DD8A002FA5C6 /* PanelTableView.swift in Sources */,
35C36F0F225961DA002FA5C6 /* TimePeriodCollection.swift in Sources */,
35C36F18225961DA002FA5C6 /* Date+Comparators.swift in Sources */,
353B5BC52698B78A0023858D /* UpcomingEventStatusItemView.swift in Sources */,
35C36FA02259ED6D002FA5C6 /* CalendarHandler.swift in Sources */,
@ -1378,12 +1365,9 @@
9AB6F1672259D23200A44663 /* PermissionsViewController.swift in Sources */,
3548C46126BEEFE400AFB533 /* UpcomingEventViewItem.swift in Sources */,
9AB6F1642259D1B900A44663 /* ParentViewController.swift in Sources */,
35C36F1C225961DA002FA5C6 /* TimePeriodChain.swift in Sources */,
3508CCAA259A0027000E3530 /* StatusContainerView.swift in Sources */,
35C36F11225961DA002FA5C6 /* TimePeriodGroup.swift in Sources */,
35C36EF922595F14002FA5C6 /* OnboardingParentViewController.swift in Sources */,
35C36F4E2259D981002FA5C6 /* DateFormatterManager.swift in Sources */,
35C36F0D225961DA002FA5C6 /* TimePeriod.swift in Sources */,
35C36EFB2259616B002FA5C6 /* Solar.swift in Sources */,
35C36F662259DF4C002FA5C6 /* UpcomingEventView.swift in Sources */,
35C36EF522595F14002FA5C6 /* OnboardingSearchController.swift in Sources */,

667
Clocker/Dependencies/Date Additions/TimePeriod.swift

@ -1,667 +0,0 @@
//
// TimePeriod.swift
// DateTools
//
// Created by Grayson Webster on 8/17/16.
// Copyright © 2016 Grayson Webster. All rights reserved.
//
import Foundation
/**
* In DateTools, time periods are represented by the TimePeriod protocol.
* Required variables and method impleementations are bound below. An inheritable
* implementation of the TimePeriodProtocol is available through the TimePeriodClass
*
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information.
*/
public protocol TimePeriodProtocol {
// MARK: - Variables
/**
* The start date for a TimePeriod representing the starting boundary of the time period
*/
var beginning: Date? { get set }
/**
* The end date for a TimePeriod representing the ending boundary of the time period
*/
var end: Date? { get set }
}
public extension TimePeriodProtocol {
// MARK: - Information
/**
* True if the `TimePeriod`'s duration is zero
*/
var isMoment: Bool {
return beginning == end
}
/**
* The duration of the `TimePeriod` in years.
* Returns the max int if beginning or end are nil.
*/
var years: Int {
if beginning != nil, end != nil {
return beginning!.yearsEarlier(than: end!)
}
return Int.max
}
/**
* The duration of the `TimePeriod` in weeks.
* Returns the max int if beginning or end are nil.
*/
var weeks: Int {
if beginning != nil, end != nil {
return beginning!.weeksEarlier(than: end!)
}
return Int.max
}
/**
* The duration of the `TimePeriod` in days.
* Returns the max int if beginning or end are nil.
*/
var days: Int {
if beginning != nil, end != nil {
return beginning!.daysEarlier(than: end!)
}
return Int.max
}
/**
* The duration of the `TimePeriod` in hours.
* Returns the max int if beginning or end are nil.
*/
var hours: Int {
if beginning != nil, end != nil {
return beginning!.hoursEarlier(than: end!)
}
return Int.max
}
/**
* The duration of the `TimePeriod` in minutes.
* Returns the max int if beginning or end are nil.
*/
var minutes: Int {
if beginning != nil, end != nil {
return beginning!.minutesEarlier(than: end!)
}
return Int.max
}
/**
* The duration of the `TimePeriod` in seconds.
* Returns the max int if beginning or end are nil.
*/
var seconds: Int {
if beginning != nil, end != nil {
return beginning!.secondsEarlier(than: end!)
}
return Int.max
}
/**
* The duration of the `TimePeriod` in a time chunk.
* Returns a time chunk with all zeroes if beginning or end are nil.
*/
var chunk: TimeChunk {
if beginning != nil, end != nil {
return beginning!.chunkBetween(date: end!)
}
return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0)
}
/**
* The length of time between the beginning and end dates of the
* `TimePeriod` as a `TimeInterval`.
*/
var duration: TimeInterval {
if beginning != nil, end != nil {
return abs(beginning!.timeIntervalSince(end!))
}
return TimeInterval(Double.greatestFiniteMagnitude)
}
// MARK: - Time Period Relationships
/**
* The relationship of the self `TimePeriod` to the given `TimePeriod`.
* Relations are stored in Enums.swift. Formal defnitions available in the provided
* links:
* [GitHub](https://github.com/MatthewYork/DateTools#relationships),
* [CodeProject](http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET)
*
* - parameter period: The time period to compare to self
*
* - returns: The relationship between self and the given time period
*/
func relation(to period: TimePeriodProtocol) -> Relation {
// Make sure that all start and end points exist for comparison
if beginning != nil, end != nil, period.beginning != nil, period.end != nil {
// Make sure time periods are of positive durations
if beginning!.isEarlier(than: end!), period.beginning!.isEarlier(than: period.end!) {
// Make comparisons
if period.end!.isEarlier(than: beginning!) {
return .after
} else if period.end!.equals(beginning!) {
return .startTouching
} else if period.beginning!.isEarlier(than: beginning!), period.end!.isEarlier(than: end!) {
return .startInside
} else if period.beginning!.equals(beginning!), period.end!.isLater(than: end!) {
return .insideStartTouching
} else if period.beginning!.equals(beginning!), period.end!.isEarlier(than: end!) {
return .enclosingStartTouching
} else if period.beginning!.isLater(than: beginning!), period.end!.isEarlier(than: end!) {
return .enclosing
} else if period.beginning!.isLater(than: beginning!), period.end!.equals(end!) {
return .enclosingEndTouching
} else if period.beginning!.equals(beginning!), period.end!.equals(end!) {
return .exactMatch
} else if period.beginning!.isEarlier(than: beginning!), period.end!.isLater(than: end!) {
return .inside
} else if period.beginning!.isEarlier(than: beginning!), period.end!.equals(end!) {
return .insideEndTouching
} else if period.beginning!.isEarlier(than: end!), period.end!.isLater(than: end!) {
return .endInside
} else if period.beginning!.equals(end!), period.end!.isLater(than: end!) {
return .endTouching
} else if period.beginning!.isLater(than: end!) {
return .before
}
}
}
return .none
}
/**
* If `self.beginning` and `self.end` are equal to the beginning and end of the
* given `TimePeriod`.
*
* - parameter period: The time period to compare to self
*
* - returns: True if the periods are the same
*/
func equals(_ period: TimePeriodProtocol) -> Bool {
return beginning == period.beginning && end == period.end
}
/**
* If the given `TimePeriod`'s beginning is before `self.beginning` and
* if the given 'TimePeriod`'s end is after `self.end`.
*
* - parameter period: The time period to compare to self
*
* - returns: True if self is inside of the given `TimePeriod`
*/
func isInside(of period: TimePeriodProtocol) -> Bool {
return period.beginning!.isEarlierThanOrEqual(to: beginning!) && period.end!.isLaterThanOrEqual(to: end!)
}
/**
* If the given Date is after `self.beginning` and before `self.end`.
*
* - parameter period: The time period to compare to self
* - parameter interval: Whether the edge of the date is included in the calculation
*
* - returns: True if the given `TimePeriod` is inside of self
*/
func contains(_ date: Date, interval: Interval) -> Bool {
if interval == .open {
return beginning!.isEarlier(than: date) && end!.isLater(than: date)
} else if interval == .closed {
return (beginning!.isEarlierThanOrEqual(to: date) && end!.isLaterThanOrEqual(to: date))
}
return false
}
/**
* If the given `TimePeriod`'s beginning is after `self.beginning` and
* if the given 'TimePeriod`'s after is after `self.end`.
*
* - parameter period: The time period to compare to self
*
* - returns: True if the given `TimePeriod` is inside of self
*/
func contains(_ period: TimePeriodProtocol) -> Bool {
return beginning!.isEarlierThanOrEqual(to: period.beginning!) && end!.isLaterThanOrEqual(to: period.end!)
}
/**
* If self and the given `TimePeriod` share any sub-`TimePeriod`.
*
* - parameter period: The time period to compare to self
*
* - returns: True if there is a period of time that is shared by both `TimePeriod`s
*/
func overlaps(with period: TimePeriodProtocol) -> Bool {
// Outside -> Inside
if period.beginning!.isEarlier(than: beginning!), period.end!.isLater(than: beginning!) {
return true
}
// Enclosing
else if period.beginning!.isLaterThanOrEqual(to: beginning!), period.end!.isEarlierThanOrEqual(to: end!) {
return true
}
// Inside -> Out
else if period.beginning!.isEarlier(than: end!), period.end!.isLater(than: end!) {
return true
}
return false
}
/**
* If self and the given `TimePeriod` overlap or the period's edges touch.
*
* - parameter period: The time period to compare to self
*
* - returns: True if there is a period of time or moment that is shared by both `TimePeriod`s
*/
func intersects(with period: TimePeriodProtocol) -> Bool {
return relation(to: period) != .after && relation(to: period) != .before
}
/**
* If self and the given `TimePeriod` have no overlap or touching edges.
*
* - parameter period: The time period to compare to self
*
* - 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 {
return isBefore(period: period) || isAfter(period: period)
}
/**
* The period of time between self and the given `TimePeriod` not contained by either.
*
* - parameter period: The time period to compare to self
*
* - returns: The gap between the periods. Zero if there is no gap.
*/
func gap(between period: TimePeriodProtocol) -> TimeInterval {
if end!.isEarlier(than: period.beginning!) {
return abs(end!.timeIntervalSince(period.beginning!))
} else if period.end!.isEarlier(than: beginning!) {
return abs(period.end!.timeIntervalSince(beginning!))
}
return 0
}
/**
* The period of time between self and the given `TimePeriod` not contained by either
* as a `TimeChunk`.
*
* - parameter period: The time period to compare to self
*
* - returns: The gap between the periods, zero if there is no gap
*/
func gap(between period: TimePeriodProtocol) -> TimeChunk? {
if end != nil, period.beginning != nil {
return (end?.chunkBetween(date: period.beginning!))!
}
return nil
}
/**
* If self is after the given `TimePeriod` chronologically. (A gap must exist between the two).
*
* - parameter period: The time period to compare to self
*
* - returns: True if self is after the given `TimePeriod`
*/
func isAfter(period: TimePeriodProtocol) -> Bool {
return relation(to: period) == .after
}
/**
* If self is before the given `TimePeriod` chronologically. (A gap must exist between the two).
*
* - parameter period: The time period to compare to self
*
* - returns: True if self is after the given `TimePeriod`
*/
func isBefore(period: TimePeriodProtocol) -> Bool {
return relation(to: period) == .before
}
// MARK: - Shifts
// MARK: In Place
/**
* In place, shift the `TimePeriod` by a `TimeInterval`
*
* - parameter timeInterval: The time interval to shift the period by
*/
mutating func shift(by timeInterval: TimeInterval) {
beginning?.addTimeInterval(timeInterval)
end?.addTimeInterval(timeInterval)
}
/**
* In place, shift the `TimePeriod` by a `TimeChunk`
*
* - parameter chunk: The time chunk to shift the period by
*/
mutating func shift(by chunk: TimeChunk) {
beginning = beginning?.add(chunk)
end = end?.add(chunk)
}
// MARK: - Lengthen / Shorten
// MARK: In Place
/**
* In place, lengthen the `TimePeriod`, anchored at the beginning, end or center
*
* - parameter timeInterval: The time interval to lengthen the period by
* - parameter anchor: The anchor point from which to make the change
*/
mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) {
switch anchor {
case .beginning:
end = end?.addingTimeInterval(timeInterval)
case .center:
beginning = beginning?.addingTimeInterval(-timeInterval / 2.0)
end = end?.addingTimeInterval(timeInterval / 2.0)
case .end:
beginning = beginning?.addingTimeInterval(-timeInterval)
}
}
/**
* In place, lengthen the `TimePeriod`, anchored at the beginning or end
*
* - parameter chunk: The time chunk to lengthen the period by
* - parameter anchor: The anchor point from which to make the change
*/
mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) {
switch anchor {
case .beginning:
end = end?.add(chunk)
case .center:
// Do not lengthen by TimeChunk at center
Swift.print("Mutation via chunk from center anchor is not supported.")
case .end:
beginning = beginning?.subtract(chunk)
}
}
/**
* In place, shorten the `TimePeriod`, anchored at the beginning, end or center
*
* - parameter timeInterval: The time interval to shorten the period by
* - parameter anchor: The anchor point from which to make the change
*/
mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) {
switch anchor {
case .beginning:
end = end?.addingTimeInterval(-timeInterval)
case .center:
beginning = beginning?.addingTimeInterval(timeInterval / 2.0)
end = end?.addingTimeInterval(-timeInterval / 2.0)
case .end:
beginning = beginning?.addingTimeInterval(timeInterval)
}
}
/**
* In place, shorten the `TimePeriod`, anchored at the beginning or end
*
* - parameter chunk: The time chunk to shorten the period by
* - parameter anchor: The anchor point from which to make the change
*/
mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) {
switch anchor {
case .beginning:
end = end?.subtract(chunk)
case .center:
// Do not shorten by TimeChunk at center
Swift.print("Mutation via chunk from center anchor is not supported.")
case .end:
beginning = beginning?.add(chunk)
}
}
}
/**
* In DateTools, time periods are represented by the case TimePeriod class
* and come with a suite of initializaiton, manipulation, and comparison methods
* to make working with them a breeze.
*
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information.
*/
open class TimePeriod: TimePeriodProtocol {
// MARK: - Variables
/**
* The start date for a TimePeriod representing the starting boundary of the time period
*/
public var beginning: Date?
/**
* The end date for a TimePeriod representing the ending boundary of the time period
*/
public var end: Date?
// MARK: - Initializers
init() {}
init(beginning: Date?, end: Date?) {
self.beginning = beginning
self.end = end
}
init(beginning: Date, duration: TimeInterval) {
self.beginning = beginning
end = beginning + duration
}
init(end: Date, duration: TimeInterval) {
self.end = end
beginning = end.addingTimeInterval(-duration)
}
init(beginning: Date, chunk: TimeChunk) {
self.beginning = beginning
end = beginning + chunk
}
init(end: Date, chunk: TimeChunk) {
self.end = end
beginning = end - chunk
}
init(chunk: TimeChunk) {
beginning = Date()
end = beginning?.add(chunk)
}
// MARK: - Shifted
/**
* Shift the `TimePeriod` by a `TimeInterval`
*
* - parameter timeInterval: The time interval to shift the period by
*
* - returns: The new, shifted `TimePeriod`
*/
func shifted(by timeInterval: TimeInterval) -> TimePeriod {
let timePeriod = TimePeriod()
timePeriod.beginning = beginning?.addingTimeInterval(timeInterval)
timePeriod.end = end?.addingTimeInterval(timeInterval)
return timePeriod
}
/**
* Shift the `TimePeriod` by a `TimeChunk`
*
* - parameter chunk: The time chunk to shift the period by
*
* - returns: The new, shifted `TimePeriod`
*/
func shifted(by chunk: TimeChunk) -> TimePeriod {
let timePeriod = TimePeriod()
timePeriod.beginning = beginning?.add(chunk)
timePeriod.end = end?.add(chunk)
return timePeriod
}
// MARK: - Lengthen / Shorten
// MARK: New
/**
* Lengthen the `TimePeriod` by a `TimeInterval`
*
* - parameter timeInterval: The time interval to lengthen the period by
* - parameter anchor: The anchor point from which to make the change
*
* - returns: The new, lengthened `TimePeriod`
*/
func lengthened(by timeInterval: TimeInterval, at anchor: Anchor) -> TimePeriod {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.beginning = beginning
timePeriod.end = end?.addingTimeInterval(timeInterval)
case .center:
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval)
timePeriod.end = end?.addingTimeInterval(timeInterval)
case .end:
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval)
timePeriod.end = end
}
return timePeriod
}
/**
* Lengthen the `TimePeriod` by a `TimeChunk`
*
* - parameter chunk: The time chunk to lengthen the period by
* - parameter anchor: The anchor point from which to make the change
*
* - returns: The new, lengthened `TimePeriod`
*/
func lengthened(by chunk: TimeChunk, at anchor: Anchor) -> TimePeriod {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.beginning = beginning
timePeriod.end = end?.add(chunk)
case .center:
Swift.print("Mutation via chunk from center anchor is not supported.")
case .end:
timePeriod.beginning = beginning?.add(-chunk)
timePeriod.end = end
}
return timePeriod
}
/**
* Shorten the `TimePeriod` by a `TimeInterval`
*
* - parameter timeInterval: The time interval to shorten the period by
* - parameter anchor: The anchor point from which to make the change
*
* - returns: The new, shortened `TimePeriod`
*/
func shortened(by timeInterval: TimeInterval, at anchor: Anchor) -> TimePeriod {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.beginning = beginning
timePeriod.end = end?.addingTimeInterval(-timeInterval)
case .center:
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval / 2)
timePeriod.end = end?.addingTimeInterval(timeInterval / 2)
case .end:
timePeriod.beginning = beginning?.addingTimeInterval(timeInterval)
timePeriod.end = end
}
return timePeriod
}
/**
* Shorten the `TimePeriod` by a `TimeChunk`
*
* - parameter chunk: The time chunk to shorten the period by
* - parameter anchor: The anchor point from which to make the change
*
* - returns: The new, shortened `TimePeriod`
*/
func shortened(by chunk: TimeChunk, at anchor: Anchor) -> TimePeriod {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.beginning = beginning
timePeriod.end = end?.subtract(chunk)
case .center:
Swift.print("Mutation via chunk from center anchor is not supported.")
case .end:
timePeriod.beginning = beginning?.add(-chunk)
timePeriod.end = end
}
return timePeriod
}
// MARK: - Operator Overloads
/**
* Operator overload for checking if two `TimePeriod`s are equal
*/
static func == (leftAddend: TimePeriod, rightAddend: TimePeriod) -> Bool {
return leftAddend.equals(rightAddend)
}
// Default anchor = beginning
/**
* Operator overload for lengthening a `TimePeriod` by a `TimeInterval`
*/
static func + (leftAddend: TimePeriod, rightAddend: TimeInterval) -> TimePeriod {
return leftAddend.lengthened(by: rightAddend, at: .beginning)
}
/**
* Operator overload for lengthening a `TimePeriod` by a `TimeChunk`
*/
static func + (leftAddend: TimePeriod, rightAddend: TimeChunk) -> TimePeriod {
return leftAddend.lengthened(by: rightAddend, at: .beginning)
}
// Default anchor = beginning
/**
* Operator overload for shortening a `TimePeriod` by a `TimeInterval`
*/
static func - (minuend: TimePeriod, subtrahend: TimeInterval) -> TimePeriod {
return minuend.shortened(by: subtrahend, at: .beginning)
}
/**
* Operator overload for shortening a `TimePeriod` by a `TimeChunk`
*/
static func - (minuend: TimePeriod, subtrahend: TimeChunk) -> TimePeriod {
return minuend.shortened(by: subtrahend, at: .beginning)
}
/**
* Operator overload for checking if a `TimePeriod` is equal to a `TimePeriodProtocol`
*/
static func == (left: TimePeriod, right: TimePeriodProtocol) -> Bool {
return left.equals(right)
}
}

177
Clocker/Dependencies/Date Additions/TimePeriodChain.swift

@ -1,177 +0,0 @@
//
// TimePeriodChain.swift
// DateTools
//
// Created by Grayson Webster on 8/17/16.
// Copyright © 2016 Grayson Webster. All rights reserved.
//
import Foundation
/**
* Time period chains serve as a tightly coupled set of time periods. They are
* always organized by start and end date, and have their own characteristics like
* a StartDate and EndDate that are extrapolated from the time periods within. Time
* period chains do not allow overlaps within their set of time periods. This type of
* group is ideal for modeling schedules like sequential meetings or appointments.
*
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-chains) for more information.
*/
open class TimePeriodChain: TimePeriodGroup {
// MARK: - Chain Existence Manipulation
/**
* Append a TimePeriodProtocol to the periods array and update the Chain's
* beginning and end.
*
* - parameter period: TimePeriodProtocol to add to the collection
*/
public func append(_ period: TimePeriodProtocol) {
let beginning = (periods.isEmpty == false) ? periods.last!.end! : period.beginning
let newPeriod = TimePeriod(beginning: beginning!, duration: period.duration)
periods.append(newPeriod)
// Update updateExtremes
if periods.count == 1 {
_beginning = period.beginning
_end = period.end
} else {
_end = _end?.addingTimeInterval(period.duration)
}
}
/**
* Append a TimePeriodProtocol array to the periods array and update the Chain's
* beginning and end.
*
* - parameter periodArray: TimePeriodProtocol list to add to the collection
*/
public func append<G: TimePeriodGroup>(contentsOf group: G) {
for period in group.periods {
let beginning = (periods.isEmpty == false) ? periods.last!.end! : period.beginning
let newPeriod = TimePeriod(beginning: beginning!, duration: period.duration)
periods.append(newPeriod)
// Update updateExtremes
if periods.count == 1 {
_beginning = period.beginning
_end = period.end
} else {
_end = _end?.addingTimeInterval(period.duration)
}
}
}
/**
* Insert period into periods array at given index.
*
* - parameter newElement: The period to insert
* - parameter index: Index to insert period at
*/
public func insert(_ period: TimePeriodProtocol, at index: Int) {
// Check for special zero case which takes the beginning date
if index == 0, period.beginning != nil, period.end != nil {
// Insert new period
periods.insert(period, at: index)
} else if period.beginning != nil, period.end != nil {
// Insert new period
periods.insert(period, at: index)
} else {
Swift.print("All TimePeriods in a TimePeriodChain must contain a defined start and end date")
return
}
// Shift all periods after inserted period
for i in 0 ..< periods.count {
if i > index, i > 0 {
let currentPeriod = TimePeriod(beginning: period.beginning, end: period.end)
periods[i].beginning = periods[i - 1].end
periods[i].end = periods[i].beginning!.addingTimeInterval(currentPeriod.duration)
}
}
updateExtremes()
}
/**
* Remove from period array at the given index.
*
* - parameter at: The index in the collection to remove
*/
public func remove(at index: Int) {
// Retrieve duration of period to be removed
let duration = periods[index].duration
// Remove period
periods.remove(at: index)
// Shift all periods after inserted period
for i in index ..< periods.count {
periods[i].shift(by: -duration)
}
updateExtremes()
}
/**
* Remove all periods from period array.
*/
public func removeAll() {
periods.removeAll()
updateExtremes()
}
// MARK: - Chain Content Manipulation
/**
* In place, shifts all chain time periods by a given time interval
*
* - parameter duration: The time interval to shift the period by
*/
public func shift(by duration: TimeInterval) {
for var period in periods {
period.shift(by: duration)
}
_beginning = _beginning?.addingTimeInterval(duration)
_end = _end?.addingTimeInterval(duration)
}
override public func map<T>(_ transform: (TimePeriodProtocol) throws -> T) rethrows -> [T] {
return try periods.map(transform)
}
override public func filter(_ isIncluded: (TimePeriodProtocol) throws -> Bool) rethrows -> [TimePeriodProtocol] {
return try periods.filter(isIncluded)
}
override internal func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result {
return try periods.reduce(initialResult, nextPartialResult)
}
/**
* Removes the last object from the `TimePeriodChain` and returns it
*
*/
public func pop() -> TimePeriodProtocol? {
let period = periods.popLast()
updateExtremes()
return period
}
internal func updateExtremes() {
_beginning = periods.first?.beginning
_end = periods.last?.end
}
// MARK: - Operator Overloads
/**
* Operator overload for comparing `TimePeriodChain`s to each other
*/
public static func == (left: TimePeriodChain, right: TimePeriodChain) -> Bool {
return left.equals(right)
}
}

267
Clocker/Dependencies/Date Additions/TimePeriodCollection.swift

@ -1,267 +0,0 @@
//
// TimePeriodCollection.swift
// DateTools
//
// Created by Grayson Webster on 8/17/16.
// Copyright © 2016 Grayson Webster. All rights reserved.
//
import Foundation
/**
* Time period collections serve as loose sets of time periods. They are
* unorganized unless you decide to sort them, and have their own characteristics
* like a `beginning` and `end` that are extrapolated from the time periods within. Time
* period collections allow overlaps within their set of time periods.
*
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-collections) for more information.
*/
open class TimePeriodCollection: TimePeriodGroup {
// MARK: - Collection Manipulation
/**
* Append a TimePeriodProtocol to the periods array and check if the Collection's
* beginning and end should change.
*
* - parameter period: TimePeriodProtocol to add to the collection
*/
public func append(_ period: TimePeriodProtocol) {
periods.append(period)
updateExtremes(period: period)
}
/**
* Append a TimePeriodProtocol array to the periods array and check if the Collection's
* beginning and end should change.
*
* - parameter periodArray: TimePeriodProtocol list to add to the collection
*/
public func append(_ periodArray: [TimePeriodProtocol]) {
for period in periodArray {
periods.append(period)
updateExtremes(period: period)
}
}
/**
* Append a TimePeriodGroup's periods array to the periods array of self and check if the Collection's
* beginning and end should change.
*
* - parameter newPeriods: TimePeriodGroup to merge periods arrays with
*/
public func append<C: TimePeriodGroup>(contentsOf newPeriods: C) {
for period in newPeriods as TimePeriodGroup {
periods.append(period)
updateExtremes(period: period)
}
}
/**
* Insert period into periods array at given index.
*
* - parameter newElement: The period to insert
* - parameter index: Index to insert period at
*/
public func insert(_ newElement: TimePeriodProtocol, at index: Int) {
periods.insert(newElement, at: index)
updateExtremes(period: newElement)
}
/**
* Remove from period array at the given index.
*
* - parameter at: The index in the collection to remove
*/
public func remove(at: Int) {
periods.remove(at: at)
updateExtremes()
}
/**
* Remove all periods from period array.
*/
public func removeAll() {
periods.removeAll()
updateExtremes()
}
// MARK: - Sorting
// In place
/**
* Sort periods array in place by beginning
*/
public func sortByBeginning() {
sort { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil, period2.beginning == nil {
return false
} else if period1.beginning == nil {
return true
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
}
}
}
/**
* Sort periods array in place
*/
public func sort(by areInIncreasingOrder: (TimePeriodProtocol, TimePeriodProtocol) -> Bool) {
periods.sort(by: areInIncreasingOrder)
}
// New collection
/**
* Return collection with sorted periods array by beginning
*
* - returns: Collection with sorted periods
*/
public func sortedByBeginning() -> TimePeriodCollection {
let array = periods.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil, period2.beginning == nil {
return false
} else if period1.beginning == nil {
return true
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
}
}
let collection = TimePeriodCollection()
collection.append(array)
return collection
}
/**
* Return collection with sorted periods array
*
* - returns: Collection with sorted periods
*/
public func sorted(by areInIncreasingOrder: (TimePeriodProtocol, TimePeriodProtocol) -> Bool) -> TimePeriodCollection {
let collection = TimePeriodCollection()
collection.append(periods.sorted(by: areInIncreasingOrder))
return collection
}
// MARK: - Collection Relationship
// Potentially use .reduce() instead of these functions
/**
* Returns from the `TimePeriodCollection` a sub-collection of `TimePeriod`s
* whose start and end dates fall completely inside the interval of the given `TimePeriod`.
*
* - parameter period: The period to compare each other period against
*
* - returns: Collection of periods inside the given period
*/
public func allInside(in period: TimePeriodProtocol) -> TimePeriodCollection {
let collection = TimePeriodCollection()
// Filter by period
collection.periods = periods.filter { (timePeriod: TimePeriodProtocol) -> Bool in
timePeriod.isInside(of: period)
}
return collection
}
/**
* Returns from the `TimePeriodCollection` a sub-collection of `TimePeriod`s containing
* the given date.
*
* - parameter date: The date to compare each period to
*
* - returns: Collection of periods intersected by the given date
*/
public func periodsIntersected(by date: Date) -> TimePeriodCollection {
let collection = TimePeriodCollection()
// Filter by period
collection.periods = periods.filter { (timePeriod: TimePeriodProtocol) -> Bool in
timePeriod.contains(date, interval: .closed)
}
return collection
}
/**
* Returns from the `TimePeriodCollection` a sub-collection of `TimePeriod`s
* containing either the start date or the end date--or both--of the given `TimePeriod`.
*
* - parameter period: The period to compare each other period to
*
* - returns: Collection of periods intersected by the given period
*/
public func periodsIntersected(by period: TimePeriodProtocol) -> TimePeriodCollection {
let collection = TimePeriodCollection()
// Filter by periop
collection.periods = periods.filter { (timePeriod: TimePeriodProtocol) -> Bool in
timePeriod.intersects(with: period)
}
return collection
}
// MARK: - Map
public func map(_ transform: (TimePeriodProtocol) throws -> TimePeriodProtocol) rethrows -> TimePeriodCollection {
var mappedArray = [TimePeriodProtocol]()
mappedArray = try periods.map(transform)
let mappedCollection = TimePeriodCollection()
for period in mappedArray {
mappedCollection.periods.append(period)
mappedCollection.updateExtremes(period: period)
}
return mappedCollection
}
// MARK: - Operator Overloads
/**
* Operator overload for comparing `TimePeriodCollection`s to each other
*/
public static func == (left: TimePeriodCollection, right: TimePeriodCollection) -> Bool {
return left.equals(right)
}
// MARK: - Helpers
internal func updateExtremes(period: TimePeriodProtocol) {
// Check incoming period against previous beginning and end date
if count == 1 {
_beginning = period.beginning
_end = period.end
} else {
_beginning = nilOrEarlier(date1: _beginning, date2: period.beginning)
_end = nilOrLater(date1: _end, date2: period.end)
}
}
internal func updateExtremes() {
if periods.isEmpty {
_beginning = nil
_end = nil
} else {
_beginning = periods[0].beginning
_end = periods[0].end
for i in 1 ..< periods.count {
_beginning = nilOrEarlier(date1: _beginning, date2: periods[i].beginning)
_end = nilOrEarlier(date1: _end, date2: periods[i].end)
}
}
}
internal func nilOrEarlier(date1: Date?, date2: Date?) -> Date? {
if date1 == nil || date2 == nil {
return nil
} else {
return date1!.earlierDate(date2!)
}
}
internal func nilOrLater(date1: Date?, date2: Date?) -> Date? {
if date1 == nil || date2 == nil {
return nil
} else {
return date1!.laterDate(date2!)
}
}
}

146
Clocker/Dependencies/Date Additions/TimePeriodGroup.swift

@ -1,146 +0,0 @@
//
// TimePeriodGroup.swift
// DateTools
//
// Created by Grayson Webster on 8/17/16.
// Copyright © 2016 Grayson Webster. All rights reserved.
//
import Foundation
/**
* Time period groups are the final abstraction of date and time in DateTools. Here, time
* periods are gathered and organized into something useful. There are two main types of time
* period groups, `TimePeriodCollection` and `TimePeriodChain`.
*
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-groups) for more information.
*/
open class TimePeriodGroup: Sequence {
// MARK: - Variables
/**
* The array of periods that define the group.
*/
internal var periods: [TimePeriodProtocol] = []
internal var _beginning: Date?
internal var _end: Date?
/**
* The earliest beginning date of a `TimePeriod` in the group.
* Nil if any `TimePeriod` in group has a nil beginning date (indefinite).
* (Read Only)
*/
public var beginning: Date? {
return _beginning
}
/**
* The latest end date of a `TimePeriod` in the group.
* Nil if any `TimePeriod` in group has a nil end date (indefinite).
* (Read Only)
*/
public var end: Date? {
return _end
}
/**
* The number of periods in the periods array.
*/
public var count: Int {
return periods.count
}
/**
* The total amount of time between the earliest and latest dates stored in the
* periods array. Nil if any beginning or end date in any contained period is nil.
*/
public var duration: TimeInterval? {
if beginning != nil, end != nil {
return end!.timeIntervalSince(beginning!)
}
return nil
}
// MARK: - Initializers
public init() {}
// MARK: - Comparisons
/**
* If `self.periods` contains the exact elements as the given group's periods array.
*
* - parameter group: The group to compare to self
*
* - returns: True if the periods arrays are the same
*/
public func equals(_ group: TimePeriodGroup) -> Bool {
return containSameElements(array1: periods, group.periods)
}
// MARK: - Sequence Protocol
public func makeIterator() -> IndexingIterator<[TimePeriodProtocol]> {
return periods.makeIterator()
}
public func map<T>(_ transform: (TimePeriodProtocol) throws -> T) rethrows -> [T] {
return try periods.map(transform)
}
public func filter(_ isIncluded: (TimePeriodProtocol) throws -> Bool) rethrows -> [TimePeriodProtocol] {
return try periods.filter(isIncluded)
}
public func forEach(_ body: (TimePeriodProtocol) throws -> Void) rethrows {
return try periods.forEach(body)
}
public func split(maxSplits: Int, omittingEmptySubsequences: Bool, whereSeparator isSeparator: (TimePeriodProtocol) throws -> Bool) rethrows -> [AnySequence<TimePeriodProtocol>] {
return try periods.split(maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, whereSeparator: isSeparator).map(AnySequence.init)
}
subscript(index: Int) -> TimePeriodProtocol {
return periods[index]
}
internal func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result {
return try periods.reduce(initialResult, nextPartialResult)
}
internal func containSameElements(array1: [TimePeriodProtocol], _ array2: [TimePeriodProtocol]) -> Bool {
guard array1.count == array2.count else {
return false // No need to sorting if they already have different counts
}
let compArray1: [TimePeriodProtocol] = array1.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil, period2.beginning == nil {
return false
} else if period1.beginning == nil {
return true
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
}
}
let compArray2: [TimePeriodProtocol] = array2.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil, period2.beginning == nil {
return false
} else if period1.beginning == nil {
return true
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
}
}
for x in 0 ..< compArray1.count {
if !compArray1[x].equals(compArray2[x]) {
return false
}
}
return true
}
}
Loading…
Cancel
Save