Files
cod-backend/Sources/App/Libraries/SwiftDate/Date/Date.swift
2020-06-14 21:46:44 -05:00

163 lines
5.7 KiB
Swift

//
// 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
#if os(Linux)
#else
internal enum AssociatedKeys: String {
case customDateFormatter = "SwiftDate.CustomDateFormatter"
}
#endif
extension Date: DateRepresentable {
/// Just return itself to be compliant with `DateRepresentable` protocol.
public var date: Date { return self }
/// For absolute Date object the default region is obtained from the global `defaultRegion` variable.
public var region: Region {
return SwiftDate.defaultRegion
}
#if os(Linux)
public var customFormatter: DateFormatter? {
get {
debugPrint("Not supported on Linux")
return nil
}
set { debugPrint("Not supported on Linux") }
}
#else
/// Assign a custom formatter if you need a special behaviour during formatting of the object.
/// Usually you will not need to do it, SwiftDate uses the local thread date formatter in order to
/// optimize the formatting process. By default is `nil`.
public var customFormatter: DateFormatter? {
get {
let fomatter: DateFormatter? = getAssociatedValue(key: AssociatedKeys.customDateFormatter.rawValue, object: self as AnyObject)
return fomatter
}
set {
set(associatedValue: newValue, key: AssociatedKeys.customDateFormatter.rawValue, object: self as AnyObject)
}
}
#endif
/// Extract the date components.
public var dateComponents: DateComponents {
return region.calendar.dateComponents(DateComponents.allComponentsSet, from: self)
}
/// Initialize a new date object from string expressed in given region.
///
/// - Parameters:
/// - string: date expressed as string.
/// - format: format of the date (`nil` uses provided list of auto formats patterns.
/// Pass it if you can in order to optimize the parse task).
/// - region: region in which the date is expressed. `nil` uses the `SwiftDate.defaultRegion`.
public init?(_ string: String, format: String? = nil, region: Region = SwiftDate.defaultRegion) {
guard let dateInRegion = DateInRegion(string, format: format, region: region) else { return nil }
self = dateInRegion.date
}
/// Initialize a new date from the number of seconds passed since Unix Epoch.
///
/// - Parameter interval: seconds
/// Initialize a new date from the number of seconds passed since Unix Epoch.
///
/// - Parameters:
/// - interval: seconds from Unix epoch time.
/// - region: region in which the date, `nil` uses the default region at UTC timezone
public init(seconds interval: TimeInterval, region: Region = Region.UTC) {
self = DateInRegion(seconds: interval, region: region).date
}
/// Initialize a new date corresponding to the number of milliseconds since the Unix Epoch.
///
/// - Parameters:
/// - interval: seconds since the Unix Epoch timestamp.
/// - region: region in which the date must be expressed, `nil` uses the default region at UTC timezone
public init(milliseconds interval: Int, region: Region = Region.UTC) {
self = DateInRegion(milliseconds: interval, region: region).date
}
/// Initialize a new date with the opportunity to configure single date components via builder pattern.
/// Date is therfore expressed in passed region (`DateComponents`'s `timezone`,`calendar` and `locale` are ignored
/// and overwritten by the region if not `nil`).
///
/// - Parameters:
/// - configuration: configuration callback
/// - region: region in which the date is expressed. Ignore to use `SwiftDate.defaultRegion`, `nil` to use `DateComponents` data.
public init?(components configuration: ((inout DateComponents) -> Void), region: Region? = SwiftDate.defaultRegion) {
guard let date = DateInRegion(components: configuration, region: region)?.date else { return nil }
self = date
}
/// Initialize a new date with given components.
///
/// - Parameters:
/// - components: components of the date.
/// - region: region in which the date is expressed.
/// Ignore to use `SwiftDate.defaultRegion`, `nil` to use `DateComponents` data.
public init?(components: DateComponents, region: Region?) {
guard let date = DateInRegion(components: components, region: region)?.date else { return nil }
self = date
}
/// Initialize a new date with given components.
public init(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int = 0, nanosecond: Int = 0, region: Region = SwiftDate.defaultRegion) {
var components = DateComponents()
components.year = year
components.month = month
components.day = day
components.hour = hour
components.minute = minute
components.second = second
components.nanosecond = nanosecond
components.timeZone = region.timeZone
components.calendar = region.calendar
self = region.calendar.date(from: components)!
}
/// Express given absolute date in the context of the default region.
///
/// - Returns: `DateInRegion`
public func inDefaultRegion() -> DateInRegion {
return DateInRegion(self, region: SwiftDate.defaultRegion)
}
/// Express given absolute date in the context of passed region.
///
/// - Parameter region: destination region.
/// - Returns: `DateInRegion`
public func `in`(region: Region) -> DateInRegion {
return DateInRegion(self, region: region)
}
/// Return a date in the distant past.
///
/// - Returns: Date instance.
public static func past() -> Date {
return Date.distantPast
}
/// Return a date in the distant future.
///
/// - Returns: Date instance.
public static func future() -> Date {
return Date.distantFuture
}
}