Skip to content

Commit e332592

Browse files
committed
Implement NSTimeZone methods and computed properties
1 parent 03995a2 commit e332592

File tree

5 files changed

+90
-49
lines changed

5 files changed

+90
-49
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ typedef pthread_t _CFThreadRef;
287287

288288
CF_EXPORT _CFThreadRef _CFThreadCreate(const _CFThreadAttributes attrs, void *_Nullable (* _Nonnull startfn)(void *_Nullable), void *restrict _Nullable context);
289289

290+
CF_EXPORT Boolean _CFTimeZoneInitWithTimeIntervalFromGMT(CFTimeZoneRef result, CFTimeInterval ti);
291+
290292
CF_EXPORT Boolean _CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, UTF32Char theChar);
291293
CF_EXPORT CFCharacterSetRef _CFCharacterSetCreateCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet);
292294
CF_EXPORT CFMutableCharacterSetRef _CFCharacterSetCreateMutableCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet);

Foundation/NSDateFormatter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ open class DateFormatter : Formatter {
148148

149149
open var generatesCalendarDates = false { willSet { _reset() } }
150150

151-
/*@NSCopying*/ open var timeZone: TimeZone! = NSTimeZone.systemTimeZone() { willSet { _reset() } }
151+
/*@NSCopying*/ open var timeZone: TimeZone! = NSTimeZone.system { willSet { _reset() } }
152152

153153
/*@NSCopying*/ internal var _calendar: Calendar! { willSet { _reset() } }
154154
open var calendar: Calendar! {

Foundation/NSTimeZone.swift

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding {
8282
// Time zones created with this never have daylight savings and the
8383
// offset is constant no matter the date; the name and abbreviation
8484
// do NOT follow the POSIX convention (of minutes-west).
85-
public convenience init(forSecondsFromGMT seconds: Int) { NSUnimplemented() }
85+
public init(forSecondsFromGMT seconds: Int) {
86+
super.init()
87+
_CFTimeZoneInitWithTimeIntervalFromGMT(_cfObject, CFTimeInterval(seconds))
88+
}
8689

8790
public convenience init?(abbreviation: String) {
8891
let abbr = abbreviation._cfObject
@@ -165,58 +168,52 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding {
165168

166169
extension NSTimeZone {
167170

168-
open class func systemTimeZone() -> TimeZone {
171+
open class var system: TimeZone {
169172
return CFTimeZoneCopySystem()._swiftObject
170173
}
171174

172175
open class func resetSystemTimeZone() {
173176
CFTimeZoneResetSystem()
177+
NotificationCenter.default.post(name: NSNotification.Name.NSSystemTimeZoneDidChange, object: nil)
174178
}
175179

176-
open class func defaultTimeZone() -> TimeZone {
177-
return CFTimeZoneCopyDefault()._swiftObject
178-
}
179-
180-
open class func setDefaultTimeZone(_ aTimeZone: TimeZone) {
181-
CFTimeZoneSetDefault(aTimeZone._cfObject)
180+
open class var `default`: TimeZone {
181+
get {
182+
return CFTimeZoneCopyDefault()._swiftObject
183+
}
184+
set {
185+
CFTimeZoneSetDefault(newValue._cfObject)
186+
NotificationCenter.default.post(name: NSNotification.Name.NSSystemTimeZoneDidChange, object: nil)
187+
}
182188
}
183-
}
184189

185-
extension NSTimeZone: _SwiftBridgable, _CFBridgable {
186-
typealias SwiftType = TimeZone
187-
var _swiftObject: TimeZone { return TimeZone(reference: self) }
188-
}
190+
open class var local: TimeZone { NSUnimplemented() }
189191

190-
extension CFTimeZone : _SwiftBridgable, _NSBridgable {
191-
typealias NSType = NSTimeZone
192-
var _nsObject : NSTimeZone { return unsafeBitCast(self, to: NSTimeZone.self) }
193-
var _swiftObject: TimeZone { return _nsObject._swiftObject }
194-
}
195-
196-
extension TimeZone : _NSBridgable, _CFBridgable {
197-
typealias NSType = NSTimeZone
198-
typealias CFType = CFTimeZone
199-
var _nsObject : NSTimeZone { return _bridgeToObjectiveC() }
200-
var _cfObject : CFTimeZone { return _nsObject._cfObject }
201-
}
192+
open class var knownTimeZoneNames: [String] {
193+
guard let knownNames = CFTimeZoneCopyKnownNames() else { return [] }
194+
return knownNames._swiftObject.map { ($0 as! NSString)._swiftObject }
195+
}
202196

203-
extension NSTimeZone {
204-
open class func localTimeZone() -> TimeZone { NSUnimplemented() }
205-
206-
open class var knownTimeZoneNames: [String] { NSUnimplemented() }
207-
208197
open class var abbreviationDictionary: [String : String] {
209198
get {
210-
NSUnimplemented()
199+
guard let dictionary = CFTimeZoneCopyAbbreviationDictionary() else { return [:] }
200+
var result = [String : String]()
201+
dictionary._swiftObject.forEach {
202+
result[($0 as! NSString)._swiftObject] = ($1 as! NSString)._swiftObject
203+
}
204+
return result
211205
}
212206
set {
213-
NSUnimplemented()
207+
CFTimeZoneSetAbbreviationDictionary(newValue._cfObject)
214208
}
215209
}
216-
210+
217211
open class var timeZoneDataVersion: String { NSUnimplemented() }
218-
219-
open var secondsFromGMT: Int { NSUnimplemented() }
212+
213+
open var secondsFromGMT: Int {
214+
let currentDate = Date()
215+
return secondsFromGMT(for: currentDate)
216+
}
220217

221218
/// The abbreviation for the receiver, such as "EDT" (Eastern Daylight Time). (read-only)
222219
///
@@ -226,15 +223,52 @@ extension NSTimeZone {
226223
return abbreviation(for: currentDate)
227224
}
228225

229-
open var daylightSavingTime: Bool { NSUnimplemented() }
230-
open var daylightSavingTimeOffset: TimeInterval { NSUnimplemented() }
231-
/*@NSCopying*/ open var nextDaylightSavingTimeTransition: Date? { NSUnimplemented() }
232-
226+
open var isDaylightSavingTime: Bool {
227+
let currentDate = Date()
228+
return isDaylightSavingTime(for: currentDate)
229+
}
230+
231+
open var daylightSavingTimeOffset: TimeInterval {
232+
let currentDate = Date()
233+
return daylightSavingTimeOffset(for: currentDate)
234+
}
235+
236+
/*@NSCopying*/ open var nextDaylightSavingTimeTransition: Date? {
237+
let currentDate = Date()
238+
return nextDaylightSavingTimeTransition(after: currentDate)
239+
}
240+
233241
open func isEqual(to aTimeZone: TimeZone) -> Bool {
234242
return CFEqual(self._cfObject, aTimeZone._cfObject)
235243
}
236-
237-
open func localizedName(_ style: NameStyle, locale: Locale?) -> String? { NSUnimplemented() }
244+
245+
open func localizedName(_ style: NameStyle, locale: Locale?) -> String? {
246+
#if os(OSX) || os(iOS)
247+
let cfStyle = CFTimeZoneNameStyle(rawValue: style.rawValue)!
248+
#else
249+
let cfStyle = CFTimeZoneNameStyle(style.rawValue)
250+
#endif
251+
return CFTimeZoneCopyLocalizedName(self._cfObject, cfStyle, locale?._cfObject)._swiftObject
252+
}
253+
254+
}
255+
256+
extension NSTimeZone: _SwiftBridgable, _CFBridgable {
257+
typealias SwiftType = TimeZone
258+
var _swiftObject: TimeZone { return TimeZone(reference: self) }
259+
}
260+
261+
extension CFTimeZone : _SwiftBridgable, _NSBridgable {
262+
typealias NSType = NSTimeZone
263+
var _nsObject : NSTimeZone { return unsafeBitCast(self, to: NSTimeZone.self) }
264+
var _swiftObject: TimeZone { return _nsObject._swiftObject }
265+
}
266+
267+
extension TimeZone : _NSBridgable, _CFBridgable {
268+
typealias NSType = NSTimeZone
269+
typealias CFType = CFTimeZone
270+
var _nsObject : NSTimeZone { return _bridgeToObjectiveC() }
271+
var _cfObject : CFTimeZone { return _nsObject._cfObject }
238272
}
239273

240274
extension NSTimeZone {
@@ -249,3 +283,7 @@ extension NSTimeZone {
249283
}
250284

251285
}
286+
287+
extension NSNotification.Name {
288+
public static let NSSystemTimeZoneDidChange = NSNotification.Name(rawValue: "NSSystemTimeZoneDidChangeNotification")
289+
}

Foundation/TimeZone.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ internal func __NSTimeZoneIsAutoupdating(_ timezone: NSTimeZone) -> Bool {
1616
return false
1717
}
1818

19-
internal func __NSTimeZoneCurrent() -> NSTimeZone {
20-
fatalError()
21-
}
22-
2319
/**
2420
`TimeZone` defines the behavior of a time zone. Time zone values represent geopolitical regions. Consequently, these values have names for these regions. Time zone values also represent a temporal offset, either plus or minus, from Greenwich Mean Time (GMT) and an abbreviation (such as PST for Pacific Standard Time).
2521

@@ -37,7 +33,12 @@ public struct TimeZone : CustomStringConvertible, CustomDebugStringConvertible,
3733

3834
/// The time zone currently used by the system.
3935
public static var current : TimeZone {
40-
return TimeZone(adoptingReference: __NSTimeZoneCurrent(), autoupdating: false)
36+
return NSTimeZone.system
37+
}
38+
39+
/// The time zone currently used by the system, automatically updating to the user’s current preference.
40+
public static var autoupdatingCurrent : TimeZone {
41+
return NSTimeZone.local
4142
}
4243

4344
// MARK: -

TestFoundation/TestNSTimeZone.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class TestNSTimeZone: XCTestCase {
3333
}
3434

3535
func test_abbreviation() {
36-
let tz = NSTimeZone.systemTimeZone()
36+
let tz = NSTimeZone.system
3737
let abbreviation1 = tz.abbreviation()
3838
let abbreviation2 = tz.abbreviation(for: Date())
3939
XCTAssertEqual(abbreviation1, abbreviation2, "\(abbreviation1) should be equal to \(abbreviation2)")
@@ -61,7 +61,7 @@ class TestNSTimeZone: XCTestCase {
6161
var t = time(nil)
6262
var lt = tm()
6363
localtime_r(&t, &lt)
64-
let zoneName = NSTimeZone.systemTimeZone().abbreviation() ?? "Invalid Abbreviation"
64+
let zoneName = NSTimeZone.system.abbreviation() ?? "Invalid Abbreviation"
6565
let expectedName = String(cString: lt.tm_zone, encoding: String.Encoding.ascii) ?? "Invalid Zone"
6666
XCTAssertEqual(zoneName, expectedName, "expected name \"\(expectedName)\" is not equal to \"\(zoneName)\"")
6767
}

0 commit comments

Comments
 (0)