Skip to content

Commit 8c3e2f2

Browse files
author
Itai Ferber
committed
Update [NS]Calendar to match API exposed by Darwin Foundation
1 parent 03995a2 commit 8c3e2f2

File tree

2 files changed

+140
-134
lines changed

2 files changed

+140
-134
lines changed

Foundation/Calendar.swift

Lines changed: 128 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ internal func __NSCalendarCurrent() -> NSCalendar {
2020
return CFCalendarCopyCurrent()._nsObject
2121
}
2222

23-
internal func __NSCalendarInit(_ identifier : String) -> NSCalendar? {
23+
internal func __NSCalendarInit(_ identifier: String) -> NSCalendar? {
2424
return NSCalendar(identifier: NSCalendar.Identifier(rawValue: identifier))
2525
}
2626

2727
/**
2828
`Calendar` encapsulates information about systems of reckoning time in which the beginning, length, and divisions of a year are defined. It provides information about the calendar and support for calendrical computations such as determining the range of a given calendrical unit and adding units to a given absolute time.
2929
*/
30-
public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible, Hashable, Equatable, ReferenceConvertible, _MutableBoxing {
30+
public struct Calendar : Hashable, Equatable, ReferenceConvertible, _MutableBoxing {
3131
public typealias ReferenceType = NSCalendar
3232

3333
internal var _autoupdating: Bool
@@ -84,9 +84,13 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
8484
}
8585

8686
/// Returns the user's current calendar. This calendar does not track changes that the user makes to their preferences.
87-
public static var current : Calendar {
87+
public static var current: Calendar {
8888
return Calendar(adoptingReference: __NSCalendarCurrent(), autoupdating: false)
8989
}
90+
91+
public static var autoupdatingCurrent: Calendar {
92+
return Calendar(adoptingReference: __NSCalendarCurrent(), autoupdating: true)
93+
}
9094

9195

9296
// MARK: -
@@ -104,7 +108,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
104108
// MARK: -
105109
// MARK: Bridging
106110

107-
internal init(reference : NSCalendar) {
111+
internal init(reference: NSCalendar) {
108112
_handle = _MutableHandle(reference: reference)
109113
if __NSCalendarIsAutoupdating(reference) {
110114
_autoupdating = true
@@ -122,12 +126,12 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
122126
//
123127

124128
/// The identifier of the calendar.
125-
public var identifier : Identifier {
129+
public var identifier: Identifier {
126130
return Calendar._fromNSCalendarIdentifier(_handle.map({ $0.calendarIdentifier }))
127131
}
128132

129133
/// The locale of the calendar.
130-
public var locale : Locale? {
134+
public var locale: Locale? {
131135
get {
132136
return _handle.map { $0.locale }
133137
}
@@ -137,7 +141,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
137141
}
138142

139143
/// The time zone of the calendar.
140-
public var timeZone : TimeZone {
144+
public var timeZone: TimeZone {
141145
get {
142146
return _handle.map { $0.timeZone }
143147
}
@@ -147,7 +151,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
147151
}
148152

149153
/// The first weekday of the calendar.
150-
public var firstWeekday : Int {
154+
public var firstWeekday: Int {
151155
get {
152156
return _handle.map { $0.firstWeekday }
153157
}
@@ -157,7 +161,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
157161
}
158162

159163
/// The number of minimum days in the first week.
160-
public var minimumDaysInFirstWeek : Int {
164+
public var minimumDaysInFirstWeek: Int {
161165
get {
162166
return _handle.map { $0.minimumDaysInFirstWeek }
163167
}
@@ -409,8 +413,8 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
409413
/// - parameter date: The specified date.
410414
/// - returns: A new `DateInterval` if the starting time and duration of a component could be calculated, otherwise `nil`.
411415
public func dateInterval(of component: Component, for date: Date) -> DateInterval? {
412-
var start : Date = Date(timeIntervalSinceReferenceDate: 0)
413-
var interval : TimeInterval = 0
416+
var start: Date = Date(timeIntervalSinceReferenceDate: 0)
417+
var interval: TimeInterval = 0
414418
if self.dateInterval(of: component, start: &start, interval: &interval, for: date) {
415419
return DateInterval(start: start, duration: interval)
416420
} else {
@@ -847,15 +851,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
847851

848852
// MARK: -
849853

850-
public var description: String {
851-
return _handle.map { $0.description }
852-
}
853-
854-
public var debugDescription : String {
855-
return _handle.map { $0.debugDescription }
856-
}
857-
858-
public var hashValue : Int {
854+
public var hashValue: Int {
859855
// We implement hash ourselves, because we need to make sure autoupdating calendars have the same hash
860856
if _autoupdating {
861857
return 1
@@ -864,12 +860,25 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
864860
}
865861
}
866862

863+
public static func ==(lhs: Calendar, rhs: Calendar) -> Bool {
864+
if lhs._autoupdating || rhs._autoupdating {
865+
return lhs._autoupdating == rhs._autoupdating
866+
} else {
867+
// NSCalendar's isEqual is broken (27019864) so we must implement this ourselves
868+
return lhs.identifier == rhs.identifier &&
869+
lhs.locale == rhs.locale &&
870+
lhs.timeZone == rhs.timeZone &&
871+
lhs.firstWeekday == rhs.firstWeekday &&
872+
lhs.minimumDaysInFirstWeek == rhs.minimumDaysInFirstWeek
873+
}
874+
}
875+
867876
// MARK: -
868877
// MARK: Conversion Functions
869878

870879
/// Turn our more-specific options into the big bucket option set of NSCalendar
871880
internal static func _toCalendarOptions(matchingPolicy: MatchingPolicy, repeatedTimePolicy: RepeatedTimePolicy, direction: SearchDirection) -> NSCalendar.Options {
872-
var result : NSCalendar.Options = []
881+
var result: NSCalendar.Options = []
873882

874883
switch matchingPolicy {
875884
case .nextTime:
@@ -899,24 +908,24 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
899908
return result
900909
}
901910

902-
internal static func _toCalendarUnit(_ units : Set<Component>) -> NSCalendar.Unit {
903-
let unitMap : [Component : NSCalendar.Unit] =
904-
[.era : .era,
905-
.year : .year,
906-
.month : .month,
907-
.day : .day,
908-
.hour : .hour,
909-
.minute : .minute,
910-
.second : .second,
911-
.weekday : .weekday,
912-
.weekdayOrdinal : .weekdayOrdinal,
913-
.quarter : .quarter,
914-
.weekOfMonth : .weekOfMonth,
915-
.weekOfYear : .weekOfYear,
916-
.yearForWeekOfYear : .yearForWeekOfYear,
917-
.nanosecond : .nanosecond,
918-
.calendar : .calendar,
919-
.timeZone : .timeZone]
911+
internal static func _toCalendarUnit(_ units: Set<Component>) -> NSCalendar.Unit {
912+
let unitMap: [Component : NSCalendar.Unit] =
913+
[.era: .era,
914+
.year: .year,
915+
.month: .month,
916+
.day: .day,
917+
.hour: .hour,
918+
.minute: .minute,
919+
.second: .second,
920+
.weekday: .weekday,
921+
.weekdayOrdinal: .weekdayOrdinal,
922+
.quarter: .quarter,
923+
.weekOfMonth: .weekOfMonth,
924+
.weekOfYear: .weekOfYear,
925+
.yearForWeekOfYear: .yearForWeekOfYear,
926+
.nanosecond: .nanosecond,
927+
.calendar: .calendar,
928+
.timeZone: .timeZone]
920929

921930
var result = NSCalendar.Unit()
922931
for u in units {
@@ -925,7 +934,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
925934
return result
926935
}
927936

928-
internal static func _fromCalendarUnit(_ unit : NSCalendar.Unit) -> Component {
937+
internal static func _fromCalendarUnit(_ unit: NSCalendar.Unit) -> Component {
929938
switch unit {
930939
case NSCalendar.Unit.era:
931940
return Component.era
@@ -964,7 +973,7 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
964973
}
965974
}
966975

967-
internal static func _fromCalendarUnits(_ units : NSCalendar.Unit) -> Set<Component> {
976+
internal static func _fromCalendarUnits(_ units: NSCalendar.Unit) -> Set<Component> {
968977
var result = Set<Component>()
969978
if units.contains(.era) {
970979
result.insert(.era)
@@ -1033,104 +1042,101 @@ public struct Calendar : CustomStringConvertible, CustomDebugStringConvertible,
10331042
return result
10341043
}
10351044

1036-
internal static func _toNSCalendarIdentifier(_ identifier : Identifier) -> NSCalendar.Identifier {
1045+
internal static func _toNSCalendarIdentifier(_ identifier: Identifier) -> NSCalendar.Identifier {
10371046
if #available(OSX 10.10, iOS 8.0, *) {
1038-
let identifierMap : [Identifier : NSCalendar.Identifier] =
1039-
[.gregorian : .gregorian,
1040-
.buddhist : .buddhist,
1041-
.chinese : .chinese,
1042-
.coptic : .coptic,
1043-
.ethiopicAmeteMihret : .ethiopicAmeteMihret,
1044-
.ethiopicAmeteAlem : .ethiopicAmeteAlem,
1045-
.hebrew : .hebrew,
1046-
.iso8601 : .ISO8601,
1047-
.indian : .indian,
1048-
.islamic : .islamic,
1049-
.islamicCivil : .islamicCivil,
1050-
.japanese : .japanese,
1051-
.persian : .persian,
1052-
.republicOfChina : .republicOfChina,
1053-
.islamicTabular : .islamicTabular,
1054-
.islamicUmmAlQura : .islamicUmmAlQura]
1047+
let identifierMap: [Identifier : NSCalendar.Identifier] =
1048+
[.gregorian: .gregorian,
1049+
.buddhist: .buddhist,
1050+
.chinese: .chinese,
1051+
.coptic: .coptic,
1052+
.ethiopicAmeteMihret: .ethiopicAmeteMihret,
1053+
.ethiopicAmeteAlem: .ethiopicAmeteAlem,
1054+
.hebrew: .hebrew,
1055+
.iso8601: .ISO8601,
1056+
.indian: .indian,
1057+
.islamic: .islamic,
1058+
.islamicCivil: .islamicCivil,
1059+
.japanese: .japanese,
1060+
.persian: .persian,
1061+
.republicOfChina: .republicOfChina,
1062+
.islamicTabular: .islamicTabular,
1063+
.islamicUmmAlQura: .islamicUmmAlQura]
10551064
return identifierMap[identifier]!
10561065
} else {
1057-
let identifierMap : [Identifier : NSCalendar.Identifier] =
1058-
[.gregorian : .gregorian,
1059-
.buddhist : .buddhist,
1060-
.chinese : .chinese,
1061-
.coptic : .coptic,
1062-
.ethiopicAmeteMihret : .ethiopicAmeteMihret,
1063-
.ethiopicAmeteAlem : .ethiopicAmeteAlem,
1064-
.hebrew : .hebrew,
1065-
.iso8601 : .ISO8601,
1066-
.indian : .indian,
1067-
.islamic : .islamic,
1068-
.islamicCivil : .islamicCivil,
1069-
.japanese : .japanese,
1070-
.persian : .persian,
1071-
.republicOfChina : .republicOfChina]
1066+
let identifierMap: [Identifier : NSCalendar.Identifier] =
1067+
[.gregorian: .gregorian,
1068+
.buddhist: .buddhist,
1069+
.chinese: .chinese,
1070+
.coptic: .coptic,
1071+
.ethiopicAmeteMihret: .ethiopicAmeteMihret,
1072+
.ethiopicAmeteAlem: .ethiopicAmeteAlem,
1073+
.hebrew: .hebrew,
1074+
.iso8601: .ISO8601,
1075+
.indian: .indian,
1076+
.islamic: .islamic,
1077+
.islamicCivil: .islamicCivil,
1078+
.japanese: .japanese,
1079+
.persian: .persian,
1080+
.republicOfChina: .republicOfChina]
10721081
return identifierMap[identifier]!
10731082
}
10741083
}
10751084

1076-
internal static func _fromNSCalendarIdentifier(_ identifier : NSCalendar.Identifier) -> Identifier {
1085+
internal static func _fromNSCalendarIdentifier(_ identifier: NSCalendar.Identifier) -> Identifier {
10771086
if #available(OSX 10.10, iOS 8.0, *) {
1078-
let identifierMap : [NSCalendar.Identifier : Identifier] =
1079-
[.gregorian : .gregorian,
1080-
.buddhist : .buddhist,
1081-
.chinese : .chinese,
1082-
.coptic : .coptic,
1083-
.ethiopicAmeteMihret : .ethiopicAmeteMihret,
1084-
.ethiopicAmeteAlem : .ethiopicAmeteAlem,
1085-
.hebrew : .hebrew,
1086-
.ISO8601 : .iso8601,
1087-
.indian : .indian,
1088-
.islamic : .islamic,
1089-
.islamicCivil : .islamicCivil,
1090-
.japanese : .japanese,
1091-
.persian : .persian,
1092-
.republicOfChina : .republicOfChina,
1093-
.islamicTabular : .islamicTabular,
1094-
.islamicUmmAlQura : .islamicUmmAlQura]
1087+
let identifierMap: [NSCalendar.Identifier : Identifier] =
1088+
[.gregorian: .gregorian,
1089+
.buddhist: .buddhist,
1090+
.chinese: .chinese,
1091+
.coptic: .coptic,
1092+
.ethiopicAmeteMihret: .ethiopicAmeteMihret,
1093+
.ethiopicAmeteAlem: .ethiopicAmeteAlem,
1094+
.hebrew: .hebrew,
1095+
.ISO8601: .iso8601,
1096+
.indian: .indian,
1097+
.islamic: .islamic,
1098+
.islamicCivil: .islamicCivil,
1099+
.japanese: .japanese,
1100+
.persian: .persian,
1101+
.republicOfChina: .republicOfChina,
1102+
.islamicTabular: .islamicTabular,
1103+
.islamicUmmAlQura: .islamicUmmAlQura]
10951104
return identifierMap[identifier]!
10961105
} else {
1097-
let identifierMap : [NSCalendar.Identifier : Identifier] =
1098-
[.gregorian : .gregorian,
1099-
.buddhist : .buddhist,
1100-
.chinese : .chinese,
1101-
.coptic : .coptic,
1102-
.ethiopicAmeteMihret : .ethiopicAmeteMihret,
1103-
.ethiopicAmeteAlem : .ethiopicAmeteAlem,
1104-
.hebrew : .hebrew,
1105-
.ISO8601 : .iso8601,
1106-
.indian : .indian,
1107-
.islamic : .islamic,
1108-
.islamicCivil : .islamicCivil,
1109-
.japanese : .japanese,
1110-
.persian : .persian,
1111-
.republicOfChina : .republicOfChina]
1106+
let identifierMap: [NSCalendar.Identifier : Identifier] =
1107+
[.gregorian: .gregorian,
1108+
.buddhist: .buddhist,
1109+
.chinese: .chinese,
1110+
.coptic: .coptic,
1111+
.ethiopicAmeteMihret: .ethiopicAmeteMihret,
1112+
.ethiopicAmeteAlem: .ethiopicAmeteAlem,
1113+
.hebrew: .hebrew,
1114+
.ISO8601: .iso8601,
1115+
.indian: .indian,
1116+
.islamic: .islamic,
1117+
.islamicCivil: .islamicCivil,
1118+
.japanese: .japanese,
1119+
.persian: .persian,
1120+
.republicOfChina: .republicOfChina]
11121121
return identifierMap[identifier]!
11131122
}
11141123
}
11151124
}
11161125

1117-
public func ==(lhs: Calendar, rhs: Calendar) -> Bool {
1118-
if lhs._autoupdating || rhs._autoupdating {
1119-
return lhs._autoupdating == rhs._autoupdating
1120-
} else {
1121-
// NSCalendar's isEqual is broken (27019864) so we must implement this ourselves
1122-
return lhs.identifier == rhs.identifier &&
1123-
lhs.locale == rhs.locale &&
1124-
lhs.timeZone == rhs.timeZone &&
1125-
lhs.firstWeekday == rhs.firstWeekday &&
1126-
lhs.minimumDaysInFirstWeek == rhs.minimumDaysInFirstWeek
1126+
extension Calendar : CustomDebugStringConvertible, CustomStringConvertible, CustomReflectable {
1127+
public var description: String {
1128+
return _handle.map { $0.description }
11271129
}
1130+
1131+
public var debugDescription: String {
1132+
return _handle.map { $0.debugDescription }
1133+
}
1134+
1135+
public var customMirror: Mirror { NSUnimplemented() }
11281136
}
11291137

1130-
extension Calendar : _ObjectTypeBridgeable {
1131-
public static func _isBridgedToObjectiveC() -> Bool {
1132-
return true
1133-
}
1138+
extension Calendar: _ObjectTypeBridgeable {
1139+
public typealias _ObjectType = NSCalendar
11341140

11351141
@_semantics("convertToObjectiveC")
11361142
public func _bridgeToObjectiveC() -> NSCalendar {
@@ -1143,6 +1149,7 @@ extension Calendar : _ObjectTypeBridgeable {
11431149
}
11441150
}
11451151

1152+
@discardableResult
11461153
public static func _conditionallyBridgeFromObjectiveC(_ input: NSCalendar, result: inout Calendar?) -> Bool {
11471154
result = Calendar(reference: input)
11481155
return true
@@ -1154,4 +1161,3 @@ extension Calendar : _ObjectTypeBridgeable {
11541161
return result!
11551162
}
11561163
}
1157-

0 commit comments

Comments
 (0)