diff --git a/Foundation/DateFormatter.swift b/Foundation/DateFormatter.swift index 31e5a69374..a1f1cae455 100644 --- a/Foundation/DateFormatter.swift +++ b/Foundation/DateFormatter.swift @@ -97,7 +97,7 @@ open class DateFormatter : Formatter { internal func _setFormatterAttributes(_ formatter: CFDateFormatter) { _setFormatterAttribute(formatter, attributeName: kCFDateFormatterIsLenient, value: isLenient._cfObject) - _setFormatterAttribute(formatter, attributeName: kCFDateFormatterTimeZone, value: timeZone?._cfObject) + _setFormatterAttribute(formatter, attributeName: kCFDateFormatterTimeZone, value: _timeZone?._cfObject) if let ident = _calendar?.identifier { _setFormatterAttribute(formatter, attributeName: kCFDateFormatterCalendarName, value: Calendar._toNSCalendarIdentifier(ident).rawValue._cfObject) } else { @@ -166,11 +166,31 @@ open class DateFormatter : Formatter { } } - /*@NSCopying*/ open var locale: Locale! = .current { willSet { _reset() } } + /*@NSCopying*/ internal var _locale: Locale? { willSet { _reset() } } + open var locale: Locale! { + get { + guard let locale = _locale else { return .current } + return locale + } + set { + _locale = newValue + } + } open var generatesCalendarDates = false { willSet { _reset() } } - /*@NSCopying*/ open var timeZone: TimeZone! = NSTimeZone.system { willSet { _reset() } } + /*@NSCopying*/ internal var _timeZone: TimeZone? { willSet { _reset() } } + open var timeZone: TimeZone! { + get { + guard let timeZone = _timeZone else { + return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterTimeZone) as! NSTimeZone)._swiftObject + } + return timeZone + } + set { + _timeZone = timeZone + } + } /*@NSCopying*/ internal var _calendar: Calendar! { willSet { _reset() } } open var calendar: Calendar! { diff --git a/TestFoundation/TestDateFormatter.swift b/TestFoundation/TestDateFormatter.swift index d0d69e9d9f..fe2346e232 100644 --- a/TestFoundation/TestDateFormatter.swift +++ b/TestFoundation/TestDateFormatter.swift @@ -22,6 +22,8 @@ class TestDateFormatter: XCTestCase { ("test_customDateFormat", test_customDateFormat), ("test_setLocalizedDateFormatFromTemplate", test_setLocalizedDateFormatFromTemplate), ("test_dateFormatString", test_dateFormatString), + ("test_setLocaleToNil", test_setLocaleToNil), + ("test_setTimeZoneToNil", test_setTimeZoneToNil), ("test_dateFrom", test_dateFrom), ] } @@ -332,6 +334,30 @@ class TestDateFormatter: XCTestCase { } } + func test_setLocaleToNil() { + let f = DateFormatter() + // Locale should be the current one by default + XCTAssertEqual(f.locale, .current) + + f.locale = nil + + // Locale should go back to current. + XCTAssertEqual(f.locale, .current) + + // A nil locale should not crash a subsequent operation + let result: String? = f.string(from: Date()) + XCTAssertNotNil(result) + } + + func test_setTimeZoneToNil() { + let f = DateFormatter() + // Time zone should be the system one by default. + XCTAssertEqual(f.timeZone, NSTimeZone.system) + f.timeZone = nil + // Time zone should go back to the system one. + XCTAssertEqual(f.timeZone, NSTimeZone.system) + } + func test_dateFrom() throws { let formatter = DateFormatter() formatter.timeZone = TimeZone(identifier: "UTC")