add all api to sort by month
This commit is contained in:
190
Sources/App/Libraries/SwiftDate/Date/Date+Compare.swift
Normal file
190
Sources/App/Libraries/SwiftDate/Date/Date+Compare.swift
Normal file
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
public extension Date {
|
||||
|
||||
// MARK: - Comparing Close
|
||||
|
||||
/// Decides whether a Date is "close by" another one passed in parameter,
|
||||
/// where "Being close" is measured using a precision argument
|
||||
/// which is initialized a 300 seconds, or 5 minutes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - refDate: reference date compare against to.
|
||||
/// - precision: The precision of the comparison (default is 5 minutes, or 300 seconds).
|
||||
/// - Returns: A boolean; true if close by, false otherwise.
|
||||
func compareCloseTo(_ refDate: Date, precision: TimeInterval = 300) -> Bool {
|
||||
return (abs(timeIntervalSince(refDate)) < precision)
|
||||
}
|
||||
|
||||
// MARK: - Extendend Compare
|
||||
|
||||
/// Compare the date with the rule specified in the `compareType` parameter.
|
||||
///
|
||||
/// - Parameter compareType: comparison type.
|
||||
/// - Returns: `true` if comparison succeded, `false` otherwise
|
||||
func compare(_ compareType: DateComparisonType) -> Bool {
|
||||
return inDefaultRegion().compare(compareType)
|
||||
}
|
||||
|
||||
/// Returns a ComparisonResult value that indicates the ordering of two given dates based on
|
||||
/// their components down to a given unit granularity.
|
||||
///
|
||||
/// - parameter date: date to compare.
|
||||
/// - parameter granularity: The smallest unit that must, along with all larger units be less for the given dates
|
||||
/// - returns: `ComparisonResult`
|
||||
func compare(toDate refDate: Date, granularity: Calendar.Component) -> ComparisonResult {
|
||||
return inDefaultRegion().compare(toDate: refDate.inDefaultRegion(), granularity: granularity)
|
||||
}
|
||||
|
||||
/// Compares whether the receiver is before/before equal `date` based on their components down to a given unit granularity.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - refDate: reference date
|
||||
/// - orEqual: `true` to also check for equality
|
||||
/// - granularity: smallest unit that must, along with all larger units, be less for the given dates
|
||||
/// - Returns: Boolean
|
||||
func isBeforeDate(_ refDate: Date, orEqual: Bool = false, granularity: Calendar.Component) -> Bool {
|
||||
return inDefaultRegion().isBeforeDate(refDate.inDefaultRegion(), orEqual: orEqual, granularity: granularity)
|
||||
}
|
||||
|
||||
/// Compares whether the receiver is after `date` based on their components down to a given unit granularity.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - refDate: reference date
|
||||
/// - orEqual: `true` to also check for equality
|
||||
/// - granularity: Smallest unit that must, along with all larger units, be greater for the given dates.
|
||||
/// - Returns: Boolean
|
||||
func isAfterDate(_ refDate: Date, orEqual: Bool = false, granularity: Calendar.Component) -> Bool {
|
||||
return inDefaultRegion().isAfterDate(refDate.inDefaultRegion(), orEqual: orEqual, granularity: granularity)
|
||||
}
|
||||
|
||||
/// Return true if receiver date is contained in the range specified by two dates.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - startDate: range upper bound date
|
||||
/// - endDate: range lower bound date
|
||||
/// - orEqual: `true` to also check for equality on date and date2
|
||||
/// - 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)
|
||||
}
|
||||
|
||||
/// Compares equality of two given dates based on their components down to a given unit
|
||||
/// granularity.
|
||||
///
|
||||
/// - parameter date: date to compare
|
||||
/// - parameter granularity: The smallest unit that must, along with all larger units, be equal for the given
|
||||
/// dates to be considered the same.
|
||||
///
|
||||
/// - returns: `true` if the dates are the same down to the given granularity, otherwise `false`
|
||||
func isInside(date: Date, granularity: Calendar.Component) -> Bool {
|
||||
return (compare(toDate: date, granularity: granularity) == .orderedSame)
|
||||
}
|
||||
|
||||
// MARK: - Date Earlier/Later
|
||||
|
||||
/// Return the earlier of two dates, between self and a given date.
|
||||
///
|
||||
/// - Parameter date: The date to compare to self
|
||||
/// - Returns: The date that is earlier
|
||||
func earlierDate(_ date: Date) -> Date {
|
||||
return timeIntervalSince(date) <= 0 ? self : date
|
||||
}
|
||||
|
||||
/// Return the later of two dates, between self and a given date.
|
||||
///
|
||||
/// - Parameter date: The date to compare to self
|
||||
/// - Returns: The date that is later
|
||||
func laterDate(_ date: Date) -> Date {
|
||||
return timeIntervalSince(date) >= 0 ? self : date
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Date {
|
||||
|
||||
/// Returns the difference in the calendar component given (like day, month or year)
|
||||
/// with respect to the other date as a positive integer
|
||||
public func difference(in component: Calendar.Component, from other: Date) -> Int? {
|
||||
let (max, min) = orderDate(with: other)
|
||||
let result = calendar.dateComponents([component], from: min, to: max)
|
||||
return getValue(of: component, from: result)
|
||||
}
|
||||
|
||||
/// Returns the differences in the calendar components given (like day, month and year)
|
||||
/// with respect to the other date as dictionary with the calendar component as the key
|
||||
/// and the diffrence as a positive integer as the value
|
||||
public func differences(in components: Set<Calendar.Component>, from other: Date) -> [Calendar.Component: Int] {
|
||||
let (max, min) = orderDate(with: other)
|
||||
let differenceInDates = calendar.dateComponents(components, from: min, to: max)
|
||||
var result = [Calendar.Component: Int]()
|
||||
for component in components {
|
||||
if let value = getValue(of: component, from: differenceInDates) {
|
||||
result[component] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private func getValue(of component: Calendar.Component, from dateComponents: DateComponents) -> Int? {
|
||||
switch component {
|
||||
case .era:
|
||||
return dateComponents.era
|
||||
case .year:
|
||||
return dateComponents.year
|
||||
case .month:
|
||||
return dateComponents.month
|
||||
case .day:
|
||||
return dateComponents.day
|
||||
case .hour:
|
||||
return dateComponents.hour
|
||||
case .minute:
|
||||
return dateComponents.minute
|
||||
case .second:
|
||||
return dateComponents.second
|
||||
case .weekday:
|
||||
return dateComponents.weekday
|
||||
case .weekdayOrdinal:
|
||||
return dateComponents.weekdayOrdinal
|
||||
case .quarter:
|
||||
return dateComponents.quarter
|
||||
case .weekOfMonth:
|
||||
return dateComponents.weekOfMonth
|
||||
case .weekOfYear:
|
||||
return dateComponents.weekOfYear
|
||||
case .yearForWeekOfYear:
|
||||
return dateComponents.yearForWeekOfYear
|
||||
case .nanosecond:
|
||||
return dateComponents.nanosecond
|
||||
case .calendar, .timeZone:
|
||||
return nil
|
||||
@unknown default:
|
||||
assert(false, "unknown date component")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func orderDate(with other: Date) -> (Date, Date) {
|
||||
let first = self.timeIntervalSince1970
|
||||
let second = other.timeIntervalSince1970
|
||||
|
||||
if first >= second {
|
||||
return (self, other)
|
||||
}
|
||||
|
||||
return (other, self)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user