forked from swiftlang/swift-corelibs-foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathISO8601DateFormatter.swift
119 lines (83 loc) · 4.97 KB
/
ISO8601DateFormatter.swift
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
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
import CoreFoundation
extension ISO8601DateFormatter {
public struct Options : OptionSet {
public private(set) var rawValue: UInt
public init(rawValue: UInt) { self.rawValue = rawValue }
public static var withYear = ISO8601DateFormatter.Options(rawValue: 1 << 0)
public static var withMonth = ISO8601DateFormatter.Options(rawValue: 1 << 1)
public static var withWeekOfYear = ISO8601DateFormatter.Options(rawValue: 1 << 2)
public static var withDay = ISO8601DateFormatter.Options(rawValue: 1 << 4)
public static var withTime = ISO8601DateFormatter.Options(rawValue: 1 << 5)
public static var withTimeZone = ISO8601DateFormatter.Options(rawValue: 1 << 6)
public static var withSpaceBetweenDateAndTime = ISO8601DateFormatter.Options(rawValue: 1 << 7)
public static var withDashSeparatorInDate = ISO8601DateFormatter.Options(rawValue: 1 << 8)
public static var withColonSeparatorInTime = ISO8601DateFormatter.Options(rawValue: 1 << 9)
public static var withColonSeparatorInTimeZone = ISO8601DateFormatter.Options(rawValue: 1 << 10)
public static var withFullDate = ISO8601DateFormatter.Options(rawValue: withYear.rawValue + withMonth.rawValue + withDay.rawValue + withDashSeparatorInDate.rawValue)
public static var withFullTime = ISO8601DateFormatter.Options(rawValue: withTime.rawValue + withTimeZone.rawValue + withColonSeparatorInTime.rawValue + withColonSeparatorInTimeZone.rawValue)
public static var withInternetDateTime = ISO8601DateFormatter.Options(rawValue: withFullDate.rawValue + withFullTime.rawValue)
}
}
open class ISO8601DateFormatter : Formatter, NSSecureCoding {
typealias CFType = CFDateFormatter
private var __cfObject: CFType?
private var _cfObject: CFType {
guard let obj = __cfObject else {
#if os(OSX) || os(iOS)
let format = CFISO8601DateFormatOptions(rawValue: formatOptions.rawValue)
#else
let format = CFISO8601DateFormatOptions(self.formatOptions.rawValue)
#endif
let obj = CFDateFormatterCreateISO8601Formatter(kCFAllocatorSystemDefault, format)!
CFDateFormatterSetProperty(obj, kCFDateFormatterTimeZone, timeZone._cfObject)
__cfObject = obj
return obj
}
return obj
}
/* Please note that there can be a significant performance cost when resetting these properties. Resetting each property can result in regenerating the entire CFDateFormatterRef, which can be very expensive. */
open var timeZone: TimeZone! { willSet { _reset() } }
open var formatOptions: ISO8601DateFormatter.Options { willSet { _reset() } }
public override init() {
timeZone = TimeZone(identifier: "GMT")
formatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withColonSeparatorInTimeZone]
super.init()
}
public required init?(coder aDecoder: NSCoder) { NSUnimplemented() }
open override func encode(with aCoder: NSCoder) { NSUnimplemented() }
public static var supportsSecureCoding: Bool { return true }
open func string(from date: Date) -> String {
return CFDateFormatterCreateStringWithDate(kCFAllocatorSystemDefault, _cfObject, date._cfObject)._swiftObject
}
open func date(from string: String) -> Date? {
var range = CFRange(location: 0, length: string.length)
let date = withUnsafeMutablePointer(to: &range) { (rangep: UnsafeMutablePointer<CFRange>) -> Date? in
guard let res = CFDateFormatterCreateDateFromString(kCFAllocatorSystemDefault, _cfObject, string._cfObject, rangep) else {
return nil
}
return res._swiftObject
}
return date
}
open class func string(from date: Date, timeZone: TimeZone, formatOptions: ISO8601DateFormatter.Options = []) -> String {
#if os(OSX) || os(iOS)
let format = CFISO8601DateFormatOptions(rawValue: formatOptions.rawValue)
#else
let format = CFISO8601DateFormatOptions(formatOptions.rawValue)
#endif
let obj = CFDateFormatterCreateISO8601Formatter(kCFAllocatorSystemDefault, format)
CFDateFormatterSetProperty(obj, kCFDateFormatterTimeZone, timeZone._cfObject)
return CFDateFormatterCreateStringWithDate(kCFAllocatorSystemDefault, obj, date._cfObject)._swiftObject
}
private func _reset() {
__cfObject = nil
}
}