宽窄优行-由【嘉易行】项目成品而来
younger_times
2023-04-06 a1ae6802080a22e6e6ce6d0935e95facb1daca5c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//
//  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
    }
 
}