Skip to content

Commit 44efa1d

Browse files
ddunn2parkera
ddunn2
authored andcommitted
Implementation of ISO8601DateFormatter (#998)
1 parent 02f09ca commit 44efa1d

7 files changed

+424
-116
lines changed

Foundation.xcodeproj/project.pbxproj

+8-8
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@
311311
61E0117F1C1B5990000037DD /* CFRunLoop.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D81BBC9AD800234F36 /* CFRunLoop.c */; };
312312
61E011811C1B5998000037DD /* CFMessagePort.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88DC1BBC9AEC00234F36 /* CFMessagePort.c */; };
313313
61E011821C1B599A000037DD /* CFMachPort.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D01BBC9AAC00234F36 /* CFMachPort.c */; };
314-
63DCE9D21EAA430100E9CB02 /* NSISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D11EAA430100E9CB02 /* NSISO8601DateFormatter.swift */; };
315-
63DCE9D41EAA432400E9CB02 /* TestNSISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D31EAA432400E9CB02 /* TestNSISO8601DateFormatter.swift */; };
314+
63DCE9D21EAA430100E9CB02 /* ISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */; };
315+
63DCE9D41EAA432400E9CB02 /* TestISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */; };
316316
6EB768281D18C12C00D4B719 /* UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EB768271D18C12C00D4B719 /* UUID.swift */; };
317317
7900433B1CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */; };
318318
7900433C1CACD33E00ECCBF1 /* TestNSPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7900433A1CACD33E00ECCBF1 /* TestNSPredicate.swift */; };
@@ -754,8 +754,8 @@
754754
61D6C9EE1C1DFE9500DEF583 /* TestNSTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSTimer.swift; sourceTree = "<group>"; };
755755
61E0117B1C1B554D000037DD /* TestNSRunLoop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSRunLoop.swift; sourceTree = "<group>"; };
756756
61F8AE7C1C180FC600FB62F0 /* TestNSNotificationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSNotificationCenter.swift; sourceTree = "<group>"; };
757-
63DCE9D11EAA430100E9CB02 /* NSISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSISO8601DateFormatter.swift; sourceTree = "<group>"; };
758-
63DCE9D31EAA432400E9CB02 /* TestNSISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSISO8601DateFormatter.swift; sourceTree = "<group>"; };
757+
63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ISO8601DateFormatter.swift; sourceTree = "<group>"; };
758+
63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestISO8601DateFormatter.swift; sourceTree = "<group>"; };
759759
6E203B8C1C1303BB003B2576 /* TestBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestBundle.swift; sourceTree = "<group>"; };
760760
6EB768271D18C12C00D4B719 /* UUID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UUID.swift; sourceTree = "<group>"; };
761761
790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSCompoundPredicate.swift; sourceTree = "<group>"; };
@@ -1430,7 +1430,7 @@
14301430
BDFDF0A61DFF5B3E00C04CC5 /* TestNSPersonNameComponents.swift */,
14311431
CD1C7F7C1E303B47008E331C /* TestNSError.swift */,
14321432
90E645DE1E4C89A400D0D47C /* TestNSCache.swift */,
1433-
63DCE9D31EAA432400E9CB02 /* TestNSISO8601DateFormatter.swift */,
1433+
63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */,
14341434
);
14351435
name = Tests;
14361436
sourceTree = "<group>";
@@ -1526,7 +1526,7 @@
15261526
5BDC3F351BCC5DCB00ED97BB /* NSDateFormatter.swift */,
15271527
5BDC3F391BCC5DCB00ED97BB /* NSFormatter.swift */,
15281528
5B628EDE1D1C995C00CA9570 /* NSMeasurementFormatter.swift */,
1529-
63DCE9D11EAA430100E9CB02 /* NSISO8601DateFormatter.swift */,
1529+
63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */,
15301530
);
15311531
name = Formatters;
15321532
sourceTree = "<group>";
@@ -2021,7 +2021,7 @@
20212021
isa = PBXSourcesBuildPhase;
20222022
buildActionMask = 2147483647;
20232023
files = (
2024-
63DCE9D21EAA430100E9CB02 /* NSISO8601DateFormatter.swift in Sources */,
2024+
63DCE9D21EAA430100E9CB02 /* ISO8601DateFormatter.swift in Sources */,
20252025
5BF7AE831BCD50CD008F214A /* NSArray.swift in Sources */,
20262026
EADE0B991BD15DFF00C49C64 /* NSEnergyFormatter.swift in Sources */,
20272027
EADE0BBF1BD15E0000C49C64 /* NSURLError.swift in Sources */,
@@ -2284,7 +2284,7 @@
22842284
5B13B3281C582D4C00651CE2 /* TestBundle.swift in Sources */,
22852285
5B13B32A1C582D4C00651CE2 /* TestNSCharacterSet.swift in Sources */,
22862286
BF8E65311DC3B3CB005AB5C3 /* TestNotification.swift in Sources */,
2287-
63DCE9D41EAA432400E9CB02 /* TestNSISO8601DateFormatter.swift in Sources */,
2287+
63DCE9D41EAA432400E9CB02 /* TestISO8601DateFormatter.swift in Sources */,
22882288
EA01AAEC1DA839C4008F4E07 /* TestProgress.swift in Sources */,
22892289
5B13B3411C582D4C00651CE2 /* TestNSRegularExpression.swift in Sources */,
22902290
5B13B3491C582D4C00651CE2 /* TestNSTimeZone.swift in Sources */,

Foundation/ISO8601DateFormatter.swift

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
import CoreFoundation
11+
12+
extension ISO8601DateFormatter {
13+
14+
public struct Options : OptionSet {
15+
16+
public private(set) var rawValue: UInt
17+
18+
public init(rawValue: UInt) { self.rawValue = rawValue }
19+
20+
public static var withYear = ISO8601DateFormatter.Options(rawValue: 1 << 0)
21+
22+
public static var withMonth = ISO8601DateFormatter.Options(rawValue: 1 << 1)
23+
24+
public static var withWeekOfYear = ISO8601DateFormatter.Options(rawValue: 1 << 2)
25+
26+
public static var withDay = ISO8601DateFormatter.Options(rawValue: 1 << 4)
27+
28+
public static var withTime = ISO8601DateFormatter.Options(rawValue: 1 << 5)
29+
30+
public static var withTimeZone = ISO8601DateFormatter.Options(rawValue: 1 << 6)
31+
32+
public static var withSpaceBetweenDateAndTime = ISO8601DateFormatter.Options(rawValue: 1 << 7)
33+
34+
public static var withDashSeparatorInDate = ISO8601DateFormatter.Options(rawValue: 1 << 8)
35+
36+
public static var withColonSeparatorInTime = ISO8601DateFormatter.Options(rawValue: 1 << 9)
37+
38+
public static var withColonSeparatorInTimeZone = ISO8601DateFormatter.Options(rawValue: 1 << 10)
39+
40+
public static var withFullDate = ISO8601DateFormatter.Options(rawValue: withYear.rawValue + withMonth.rawValue + withDay.rawValue + withDashSeparatorInDate.rawValue)
41+
42+
public static var withFullTime = ISO8601DateFormatter.Options(rawValue: withTime.rawValue + withTimeZone.rawValue + withColonSeparatorInTime.rawValue + withColonSeparatorInTimeZone.rawValue)
43+
44+
public static var withInternetDateTime = ISO8601DateFormatter.Options(rawValue: withFullDate.rawValue + withFullTime.rawValue)
45+
}
46+
47+
}
48+
49+
open class ISO8601DateFormatter : Formatter, NSSecureCoding {
50+
51+
typealias CFType = CFDateFormatter
52+
private var __cfObject: CFType?
53+
private var _cfObject: CFType {
54+
guard let obj = __cfObject else {
55+
#if os(OSX) || os(iOS)
56+
let format = CFISO8601DateFormatOptions(rawValue: formatOptions.rawValue)
57+
#else
58+
let format = CFISO8601DateFormatOptions(self.formatOptions.rawValue)
59+
#endif
60+
let obj = CFDateFormatterCreateISO8601Formatter(kCFAllocatorSystemDefault, format)!
61+
CFDateFormatterSetProperty(obj, kCFDateFormatterTimeZone, timeZone._cfObject)
62+
__cfObject = obj
63+
return obj
64+
}
65+
return obj
66+
}
67+
68+
/* 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. */
69+
70+
open var timeZone: TimeZone! { willSet { _reset() } }
71+
72+
open var formatOptions: ISO8601DateFormatter.Options { willSet { _reset() } }
73+
74+
public override init() {
75+
timeZone = TimeZone(identifier: "GMT")
76+
formatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withColonSeparatorInTimeZone]
77+
super.init()
78+
}
79+
80+
public required init?(coder aDecoder: NSCoder) { NSUnimplemented() }
81+
open override func encode(with aCoder: NSCoder) { NSUnimplemented() }
82+
public static var supportsSecureCoding: Bool { return true }
83+
84+
open func string(from date: Date) -> String {
85+
return CFDateFormatterCreateStringWithDate(kCFAllocatorSystemDefault, _cfObject, date._cfObject)._swiftObject
86+
}
87+
88+
open func date(from string: String) -> Date? {
89+
90+
var range = CFRange(location: 0, length: string.length)
91+
let date = withUnsafeMutablePointer(to: &range) { (rangep: UnsafeMutablePointer<CFRange>) -> Date? in
92+
guard let res = CFDateFormatterCreateDateFromString(kCFAllocatorSystemDefault, _cfObject, string._cfObject, rangep) else {
93+
return nil
94+
}
95+
return res._swiftObject
96+
}
97+
return date
98+
99+
}
100+
101+
open class func string(from date: Date, timeZone: TimeZone, formatOptions: ISO8601DateFormatter.Options = []) -> String {
102+
103+
#if os(OSX) || os(iOS)
104+
let format = CFISO8601DateFormatOptions(rawValue: formatOptions.rawValue)
105+
#else
106+
let format = CFISO8601DateFormatOptions(formatOptions.rawValue)
107+
#endif
108+
109+
let obj = CFDateFormatterCreateISO8601Formatter(kCFAllocatorSystemDefault, format)
110+
CFDateFormatterSetProperty(obj, kCFDateFormatterTimeZone, timeZone._cfObject)
111+
return CFDateFormatterCreateStringWithDate(kCFAllocatorSystemDefault, obj, date._cfObject)._swiftObject
112+
113+
}
114+
115+
private func _reset() {
116+
__cfObject = nil
117+
}
118+
119+
}

Foundation/NSISO8601DateFormatter.swift

-79
This file was deleted.

0 commit comments

Comments
 (0)