add all api to sort by month

This commit is contained in:
Michael Simard
2020-06-14 21:46:44 -05:00
parent 6b9e9a4c35
commit 842abb0895
162 changed files with 34480 additions and 71 deletions

View File

@@ -0,0 +1,199 @@
//
// SwiftDate
// Parse, validate, manipulate, and display dates, time and timezones in Swift
//
// Created by Daniele Margutti
// - Web: https://www.danielemargutti.com
// - Twitter: https://twitter.com/danielemargutti
// - Mail: hello@danielemargutti.com
//
// Copyright © 2019 Daniele Margutti. Licensed under MIT License.
//
import Foundation
/// Time periods are represented by the TimePeriodProtocol protocol.
/// Required variables and method impleementations are bound below.
/// An inheritable implementation of the TimePeriodProtocol is available through the TimePeriod class.
open class TimePeriod: TimePeriodProtocol {
/// The start date for a TimePeriod representing the starting boundary of the time period
public var start: DateInRegion?
/// The end date for a TimePeriod representing the ending boundary of the time period
public var end: DateInRegion?
// MARK: - Initializers
public init() { }
/// Create a new time period with given date range.
///
/// - Parameters:
/// - start: start date
/// - end: end date
public init(start: DateInRegion?, end: DateInRegion?) {
self.start = start
self.end = end
}
/// Create a new time period with given start and a length specified in number of seconds.
///
/// - Parameters:
/// - start: start of the period
/// - duration: duration of the period expressed in seconds
public init(start: DateInRegion, duration: TimeInterval) {
self.start = start
self.end = DateInRegion(start.date.addingTimeInterval(duration), region: start.region)
}
/// Create a new time period which ends at given date and start date is back on time by given interval.
///
/// - Parameters:
/// - end: end date
/// - duration: duration expressed in seconds (it will be subtracted from start date)
public init(end: DateInRegion, duration: TimeInterval) {
self.end = end
self.start = end.addingTimeInterval(-duration)
}
/// Return a new instance of the TimePeriod that starts on the provided start date and is of the
/// size provided.
///
/// - Parameters:
/// - start: start of the period
/// - duration: length of the period (ie. `2.days` or `14.hours`...)
public init(start: DateInRegion, duration: DateComponents) {
self.start = start
self.end = (start + duration)
}
/// Return a new instance of the TimePeriod that starts at end time minus given duration.
///
/// - Parameters:
/// - end: end date
/// - duration: duration (it will be subtracted from end date in order to provide the start date)
public init(end: DateInRegion, duration: DateComponents) {
self.start = (end - duration)
self.end = end
}
/// Returns a new instance of DTTimePeriod that represents the largest time period available.
/// The start date is in the distant past and the end date is in the distant future.
///
/// - Returns: a new time period
public static func infinity() -> TimePeriod {
return TimePeriod(start: DateInRegion.past(), end: DateInRegion.future())
}
// MARK: - Shifted
/// Shift the `TimePeriod` by a `TimeInterval`
///
/// - Parameter timeInterval: The time interval to shift the period by
/// - Returns: The new, shifted `TimePeriod`
public func shifted(by timeInterval: TimeInterval) -> TimePeriod {
let timePeriod = TimePeriod()
timePeriod.start = start?.addingTimeInterval(timeInterval)
timePeriod.end = end?.addingTimeInterval(timeInterval)
return timePeriod
}
/// Shift the `TimePeriod` by the specified components value.
/// ie. `let shifted = period.shifted(by: 3.days)`
///
/// - Parameter components: components to shift
/// - Returns: new period
public func shifted(by components: DateComponents) -> TimePeriod {
let timePeriod = TimePeriod()
timePeriod.start = (hasStart ? (start! + components) : nil)
timePeriod.end = (hasEnd ? (end! + components) : nil)
return timePeriod
}
// MARK: - Lengthen / Shorten
/// Lengthen the `TimePeriod` by a `TimeInterval`
///
/// - Parameters:
/// - timeInterval: The time interval to lengthen the period by
/// - anchor: The anchor point from which to make the change
/// - Returns: The new, lengthened `TimePeriod`
public func lengthened(by timeInterval: TimeInterval, at anchor: TimePeriodAnchor) -> TimePeriod {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.start = start
timePeriod.end = end?.addingTimeInterval(timeInterval)
case .center:
timePeriod.start = start?.addingTimeInterval(-timeInterval)
timePeriod.end = end?.addingTimeInterval(timeInterval)
case .end:
timePeriod.start = start?.addingTimeInterval(-timeInterval)
timePeriod.end = end
}
return timePeriod
}
/// Shorten the `TimePeriod` by a `TimeInterval`
///
/// - Parameters:
/// - timeInterval: The time interval to shorten the period by
/// - anchor: The anchor point from which to make the change
/// - Returns: The new, shortened `TimePeriod`
public func shortened(by timeInterval: TimeInterval, at anchor: TimePeriodAnchor) -> TimePeriod {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.start = start
timePeriod.end = end?.addingTimeInterval(-timeInterval)
case .center:
timePeriod.start = start?.addingTimeInterval(-timeInterval / 2)
timePeriod.end = end?.addingTimeInterval(timeInterval / 2)
case .end:
timePeriod.start = start?.addingTimeInterval(timeInterval)
timePeriod.end = end
}
return timePeriod
}
// MARK: - Operator Overloads
/// Default anchor = beginning
/// Operator overload for lengthening a `TimePeriod` by a `TimeInterval`
public static func + (leftAddend: TimePeriod, rightAddend: TimeInterval) -> TimePeriod {
return leftAddend.lengthened(by: rightAddend, at: .beginning)
}
/// Default anchor = beginning
/// Operator overload for shortening a `TimePeriod` by a `TimeInterval`
public static func - (minuend: TimePeriod, subtrahend: TimeInterval) -> TimePeriod {
return minuend.shortened(by: subtrahend, at: .beginning)
}
/// Operator overload for checking if a `TimePeriod` is equal to a `TimePeriodProtocol`
public static func == (left: TimePeriod, right: TimePeriodProtocol) -> Bool {
return left.equals(right)
}
}
public extension TimePeriod {
/// The start date of the time period
var startDate: Date? {
return start?.date
}
/// The end date of the time period
var endDate: Date? {
return end?.date
}
/// Create a new time period with the given start date, end date and region (default is UTC)
convenience init(startDate: Date, endDate: Date, region: Region = Region.UTC) {
let start = DateInRegion(startDate, region: region)
let end = DateInRegion(endDate, region: region)
self.init(start: start, end: end)
}
}