Skip to content

Commit 3ceecb1

Browse files
committed
SR-10619: Order in which DateFormatter settings are set up matters on Linux
- Ensure the setting of .dateStyle and .timeStyle isnt dependant on the current setting of .locale.
1 parent dea5c12 commit 3ceecb1

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

Foundation/DateFormatter.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ open class DateFormatter : Formatter {
2121
let dateStyle = CFDateFormatterStyle(self.dateStyle.rawValue)
2222
let timeStyle = CFDateFormatterStyle(self.timeStyle.rawValue)
2323
#endif
24-
24+
2525
let obj = CFDateFormatterCreate(kCFAllocatorSystemDefault, locale._cfObject, dateStyle, timeStyle)!
2626
_setFormatterAttributes(obj)
2727
if let dateFormat = _dateFormat {
@@ -144,7 +144,7 @@ open class DateFormatter : Formatter {
144144
open var dateFormat: String! {
145145
get {
146146
guard let format = _dateFormat else {
147-
return __cfObject.map { CFDateFormatterGetFormat($0)._swiftObject } ?? ""
147+
return CFDateFormatterGetFormat(_cfObject)._swiftObject
148148
}
149149
return format
150150
}
@@ -157,18 +157,12 @@ open class DateFormatter : Formatter {
157157
willSet {
158158
_dateFormat = nil
159159
}
160-
didSet {
161-
_dateFormat = CFDateFormatterGetFormat(_cfObject)._swiftObject
162-
}
163160
}
164161

165162
open var timeStyle: Style = .none {
166163
willSet {
167164
_dateFormat = nil
168165
}
169-
didSet {
170-
_dateFormat = CFDateFormatterGetFormat(_cfObject)._swiftObject
171-
}
172166
}
173167

174168
/*@NSCopying*/ internal var _locale: Locale? { willSet { _reset() } }

TestFoundation/TestDateFormatter.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class TestDateFormatter: XCTestCase {
2828
("test_expectedTimeZone", test_expectedTimeZone),
2929
("test_dateFrom", test_dateFrom),
3030
("test_dateParseAndFormatWithJapaneseCalendar", test_dateParseAndFormatWithJapaneseCalendar),
31+
("test_orderOfPropertySetters", test_orderOfPropertySetters),
3132
]
3233
}
3334

@@ -443,4 +444,64 @@ class TestDateFormatter: XCTestCase {
443444
let dateString = formatter.string(from: Date(timeIntervalSince1970: 1556633400)) // April 30, 2019, 11:10 PM (JST)
444445
XCTAssertEqual(dateString, "平成31年4月30日 23:10")
445446
}
447+
448+
func test_orderOfPropertySetters() throws {
449+
450+
// This produces a .count factorial number of arrays
451+
func combinations<T>(of a: [T]) -> [[T]] {
452+
precondition(!a.isEmpty)
453+
if a.count == 1 { return [a] }
454+
if a.count == 2 { return [ [a[0], a[1]], [ a[1], a[0]] ] }
455+
456+
var result: [[T]] = []
457+
458+
for idx in a.startIndex..<a.endIndex {
459+
let x = a[idx]
460+
var b: [T] = a
461+
b.remove(at: idx)
462+
463+
for var c in combinations(of: b) {
464+
c.append(x)
465+
result.append(c)
466+
}
467+
}
468+
return result
469+
}
470+
471+
let formatter = DateFormatter()
472+
formatter.timeZone = TimeZone(identifier: "CET")
473+
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
474+
let date = try formatter.date(from: "2019-05-05T12:52:10").unwrapped()
475+
476+
let applySettings: [(String, (DateFormatter) -> Void)] =
477+
[(".timeZone", {
478+
$0.timeZone = TimeZone(identifier: "Europe/Oslo")
479+
}),
480+
(".calendar", {
481+
$0.calendar = Calendar(identifier: .gregorian)
482+
}),
483+
(".locale", {
484+
$0.locale = Locale(identifier: "nb")
485+
}),
486+
(".dateStyle", {
487+
$0.dateStyle = .medium
488+
}),
489+
(".timeStyle", {
490+
$0.timeStyle = .medium
491+
})
492+
]
493+
494+
// Test all of the combinations of setting the properties produces the same output
495+
let expected = "5. mai 2019, 12:52:10"
496+
for settings in combinations(of: applySettings) {
497+
let f = DateFormatter()
498+
settings.forEach { $0.1(f) }
499+
XCTAssertEqual(f.dateFormat, "d. MMM y, HH:mm:ss")
500+
let formattedString = f.string(from: date)
501+
if formattedString != expected {
502+
let applied = settings.map { $0.0 }.joined(separator: ",")
503+
XCTFail("\(formattedString) != \(expected) using settings applied in order \(applied)")
504+
}
505+
}
506+
}
446507
}

0 commit comments

Comments
 (0)