Skip to content

Commit 9ec23d4

Browse files
authored
Merge pull request #2160 from spevans/pr_sr_10516
SR-10516: TimeZone.nextDaylightSavingTimeTransition does not return nil
2 parents 2a604a4 + 812d234 commit 9ec23d4

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

Foundation/NSTimeZone.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding {
176176
guard type(of: self) === NSTimeZone.self else {
177177
NSRequiresConcreteImplementation()
178178
}
179-
return Date(timeIntervalSinceReferenceDate: CFTimeZoneGetNextDaylightSavingTimeTransition(_cfObject, aDate.timeIntervalSinceReferenceDate))
179+
let ti = CFTimeZoneGetNextDaylightSavingTimeTransition(_cfObject, aDate.timeIntervalSinceReferenceDate)
180+
guard ti > 0 else { return nil }
181+
return Date(timeIntervalSinceReferenceDate: ti)
180182
}
181183

182184
open class var system: TimeZone {

TestFoundation/TestTimeZone.swift

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10-
import CoreFoundation
1110

1211
class TestTimeZone: XCTestCase {
1312

@@ -228,7 +227,39 @@ class TestTimeZone: XCTestCase {
228227
}
229228
}
230229
}
231-
230+
231+
func test_nextDaylightSavingTimeTransition() throws {
232+
// Timezones without DST
233+
let gmt = try TimeZone(secondsFromGMT: 0).unwrapped()
234+
let msk = try TimeZone(identifier: "Europe/Moscow").unwrapped()
235+
236+
// Timezones with DST
237+
let bst = try TimeZone(abbreviation: "BST").unwrapped()
238+
let aest = try TimeZone(identifier: "Australia/Sydney").unwrapped()
239+
240+
XCTAssertNil(gmt.nextDaylightSavingTimeTransition)
241+
XCTAssertNil(msk.nextDaylightSavingTimeTransition)
242+
XCTAssertNotNil(bst.nextDaylightSavingTimeTransition)
243+
XCTAssertNotNil(aest.nextDaylightSavingTimeTransition)
244+
245+
let formatter = DateFormatter()
246+
formatter.timeZone = TimeZone(identifier: "UTC")
247+
formatter.dateFormat = "yyyy-MM-dd"
248+
249+
let dt1 = try formatter.date(from: "2018-01-01").unwrapped()
250+
XCTAssertNil(gmt.nextDaylightSavingTimeTransition(after: dt1))
251+
XCTAssertNil(msk.nextDaylightSavingTimeTransition(after: dt1))
252+
XCTAssertEqual(bst.nextDaylightSavingTimeTransition(after: dt1)?.description, "2018-03-25 01:00:00 +0000")
253+
XCTAssertEqual(aest.nextDaylightSavingTimeTransition(after: dt1)?.description, "2018-03-31 16:00:00 +0000")
254+
255+
formatter.timeZone = aest
256+
let dt2 = try formatter.date(from: "2018-06-06").unwrapped()
257+
XCTAssertNil(gmt.nextDaylightSavingTimeTransition(after: dt2))
258+
XCTAssertNil(msk.nextDaylightSavingTimeTransition(after: dt2))
259+
XCTAssertEqual(bst.nextDaylightSavingTimeTransition(after: dt2)?.description, "2018-10-28 01:00:00 +0000")
260+
XCTAssertEqual(aest.nextDaylightSavingTimeTransition(after: dt2)?.description, "2018-10-06 16:00:00 +0000")
261+
}
262+
232263
static var allTests: [(String, (TestTimeZone) -> () throws -> Void)] {
233264
var tests: [(String, (TestTimeZone) -> () throws -> Void)] = [
234265
("test_abbreviation", test_abbreviation),
@@ -247,6 +278,7 @@ class TestTimeZone: XCTestCase {
247278
("test_knownTimeZones", test_knownTimeZones),
248279
("test_systemTimeZoneName", test_systemTimeZoneName),
249280
("test_autoupdatingTimeZone", test_autoupdatingTimeZone),
281+
("test_nextDaylightSavingTimeTransition", test_nextDaylightSavingTimeTransition),
250282
]
251283

252284
#if !os(Windows)

0 commit comments

Comments
 (0)