| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See http://swift.org/LICENSE.txt for license information |
| // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| |
| class TestDateFormatter: XCTestCase { |
| |
| let DEFAULT_LOCALE = "en_US_POSIX" |
| let DEFAULT_TIMEZONE = "GMT" |
| |
| static var allTests : [(String, (TestDateFormatter) -> () throws -> Void)] { |
| return [ |
| ("test_BasicConstruction", test_BasicConstruction), |
| ("test_dateStyleShort", test_dateStyleShort), |
| //("test_dateStyleMedium", test_dateStyleMedium), |
| ("test_dateStyleLong", test_dateStyleLong), |
| ("test_dateStyleFull", test_dateStyleFull), |
| ("test_customDateFormat", test_customDateFormat), |
| ("test_setLocalizedDateFormatFromTemplate", test_setLocalizedDateFormatFromTemplate), |
| ("test_dateFormatString", test_dateFormatString), |
| ("test_setLocaleToNil", test_setLocaleToNil), |
| ("test_setTimeZoneToNil", test_setTimeZoneToNil), |
| ("test_setTimeZone", test_setTimeZone), |
| ("test_expectedTimeZone", test_expectedTimeZone), |
| ("test_dateFrom", test_dateFrom), |
| ("test_dateParseAndFormatWithJapaneseCalendar", test_dateParseAndFormatWithJapaneseCalendar), |
| ("test_orderOfPropertySetters", test_orderOfPropertySetters), |
| ] |
| } |
| |
| func test_BasicConstruction() { |
| |
| let symbolDictionaryOne = ["eraSymbols" : ["BC", "AD"], |
| "monthSymbols" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], |
| "shortMonthSymbols" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], |
| "weekdaySymbols" : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], |
| "shortWeekdaySymbols" : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], |
| "longEraSymbols" : ["Before Christ", "Anno Domini"], |
| "veryShortMonthSymbols" : ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], |
| "standaloneMonthSymbols" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], |
| "shortStandaloneMonthSymbols" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], |
| "veryShortStandaloneMonthSymbols" : ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]] |
| |
| let symbolDictionaryTwo = ["veryShortWeekdaySymbols" : ["S", "M", "T", "W", "T", "F", "S"], |
| "standaloneWeekdaySymbols" : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], |
| "shortStandaloneWeekdaySymbols" : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], |
| "veryShortStandaloneWeekdaySymbols" : ["S", "M", "T", "W", "T", "F", "S"], |
| "quarterSymbols" : ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"], |
| "shortQuarterSymbols" : ["Q1", "Q2", "Q3", "Q4"], |
| "standaloneQuarterSymbols" : ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"], |
| "shortStandaloneQuarterSymbols" : ["Q1", "Q2", "Q3", "Q4"]] |
| |
| let f = DateFormatter() |
| XCTAssertNotNil(f.timeZone) |
| XCTAssertNotNil(f.locale) |
| |
| f.timeZone = TimeZone(identifier: DEFAULT_TIMEZONE) |
| f.locale = Locale(identifier: DEFAULT_LOCALE) |
| |
| // Assert default values are set properly |
| XCTAssertFalse(f.generatesCalendarDates) |
| XCTAssertNotNil(f.calendar) |
| XCTAssertFalse(f.isLenient) |
| XCTAssertEqual(f.twoDigitStartDate!, Date(timeIntervalSince1970: -631152000)) |
| XCTAssertNil(f.defaultDate) |
| XCTAssertEqual(f.eraSymbols, symbolDictionaryOne["eraSymbols"]!) |
| XCTAssertEqual(f.monthSymbols, symbolDictionaryOne["monthSymbols"]!) |
| XCTAssertEqual(f.shortMonthSymbols, symbolDictionaryOne["shortMonthSymbols"]!) |
| XCTAssertEqual(f.weekdaySymbols, symbolDictionaryOne["weekdaySymbols"]!) |
| XCTAssertEqual(f.shortWeekdaySymbols, symbolDictionaryOne["shortWeekdaySymbols"]!) |
| XCTAssertEqual(f.amSymbol, "AM") |
| XCTAssertEqual(f.pmSymbol, "PM") |
| XCTAssertEqual(f.longEraSymbols, symbolDictionaryOne["longEraSymbols"]!) |
| XCTAssertEqual(f.veryShortMonthSymbols, symbolDictionaryOne["veryShortMonthSymbols"]!) |
| XCTAssertEqual(f.standaloneMonthSymbols, symbolDictionaryOne["standaloneMonthSymbols"]!) |
| XCTAssertEqual(f.shortStandaloneMonthSymbols, symbolDictionaryOne["shortStandaloneMonthSymbols"]!) |
| XCTAssertEqual(f.veryShortStandaloneMonthSymbols, symbolDictionaryOne["veryShortStandaloneMonthSymbols"]!) |
| XCTAssertEqual(f.veryShortWeekdaySymbols, symbolDictionaryTwo["veryShortWeekdaySymbols"]!) |
| XCTAssertEqual(f.standaloneWeekdaySymbols, symbolDictionaryTwo["standaloneWeekdaySymbols"]!) |
| XCTAssertEqual(f.shortStandaloneWeekdaySymbols, symbolDictionaryTwo["shortStandaloneWeekdaySymbols"]!) |
| XCTAssertEqual(f.veryShortStandaloneWeekdaySymbols, symbolDictionaryTwo["veryShortStandaloneWeekdaySymbols"]!) |
| XCTAssertEqual(f.quarterSymbols, symbolDictionaryTwo["quarterSymbols"]!) |
| XCTAssertEqual(f.shortQuarterSymbols, symbolDictionaryTwo["shortQuarterSymbols"]!) |
| XCTAssertEqual(f.standaloneQuarterSymbols, symbolDictionaryTwo["standaloneQuarterSymbols"]!) |
| XCTAssertEqual(f.shortStandaloneQuarterSymbols, symbolDictionaryTwo["shortStandaloneQuarterSymbols"]!) |
| XCTAssertEqual(f.gregorianStartDate, Date(timeIntervalSince1970: -12219292800)) |
| XCTAssertFalse(f.doesRelativeDateFormatting) |
| |
| } |
| |
| // ShortStyle |
| // locale stringFromDate example |
| // ------ -------------- -------- |
| // en_US M/d/yy h:mm a 12/25/15 12:00 AM |
| func test_dateStyleShort() { |
| |
| let timestamps = [ |
| -31536000 : "1/1/69, 12:00 AM" , 0.0 : "1/1/70, 12:00 AM", 31536000 : "1/1/71, 12:00 AM", |
| 2145916800 : "1/1/38, 12:00 AM", 1456272000 : "2/24/16, 12:00 AM", 1456358399 : "2/24/16, 11:59 PM", |
| 1452574638 : "1/12/16, 4:57 AM", 1455685038 : "2/17/16, 4:57 AM", 1458622638 : "3/22/16, 4:57 AM", |
| 1459745838 : "4/4/16, 4:57 AM", 1462597038 : "5/7/16, 4:57 AM", 1465534638 : "6/10/16, 4:57 AM", |
| 1469854638 : "7/30/16, 4:57 AM", 1470718638 : "8/9/16, 4:57 AM", 1473915438 : "9/15/16, 4:57 AM", |
| 1477285038 : "10/24/16, 4:57 AM", 1478062638 : "11/2/16, 4:57 AM", 1482641838 : "12/25/16, 4:57 AM" |
| ] |
| |
| let f = DateFormatter() |
| f.dateStyle = .short |
| f.timeStyle = .short |
| |
| // ensure tests give consistent results by setting specific timeZone and locale |
| f.timeZone = TimeZone(identifier: DEFAULT_TIMEZONE) |
| f.locale = Locale(identifier: DEFAULT_LOCALE) |
| |
| for (timestamp, stringResult) in timestamps { |
| |
| let testDate = Date(timeIntervalSince1970: timestamp) |
| let sf = f.string(from: testDate) |
| |
| XCTAssertEqual(sf, stringResult) |
| } |
| |
| } |
| |
| // MediumStyle |
| // locale stringFromDate example |
| // ------ -------------- ------------ |
| // en_US MMM d, y, h:mm:ss a Dec 25, 2015, 12:00:00 AM |
| func test_dateStyleMedium() { |
| |
| let timestamps = [ |
| -31536000 : "Jan 1, 1969, 12:00:00 AM" , 0.0 : "Jan 1, 1970, 12:00:00 AM", 31536000 : "Jan 1, 1971, 12:00:00 AM", |
| 2145916800 : "Jan 1, 2038, 12:00:00 AM", 1456272000 : "Feb 24, 2016, 12:00:00 AM", 1456358399 : "Feb 24, 2016, 11:59:59 PM", |
| 1452574638 : "Jan 12, 2016, 4:57:18 AM", 1455685038 : "Feb 17, 2016, 4:57:18 AM", 1458622638 : "Mar 22, 2016, 4:57:18 AM", |
| 1459745838 : "Apr 4, 2016, 4:57:18 AM", 1462597038 : "May 7, 2016, 4:57:18 AM", 1465534638 : "Jun 10, 2016, 4:57:18 AM", |
| 1469854638 : "Jul 30, 2016, 4:57:18 AM", 1470718638 : "Aug 9, 2016, 4:57:18 AM", 1473915438 : "Sep 15, 2016, 4:57:18 AM", |
| 1477285038 : "Oct 24, 2016, 4:57:18 AM", 1478062638 : "Nov 2, 2016, 4:57:18 AM", 1482641838 : "Dec 25, 2016, 4:57:18 AM" |
| ] |
| |
| let f = DateFormatter() |
| f.dateStyle = .medium |
| f.timeStyle = .medium |
| f.timeZone = TimeZone(identifier: DEFAULT_TIMEZONE) |
| f.locale = Locale(identifier: DEFAULT_LOCALE) |
| |
| for (timestamp, stringResult) in timestamps { |
| |
| let testDate = Date(timeIntervalSince1970: timestamp) |
| let sf = f.string(from: testDate) |
| |
| XCTAssertEqual(sf, stringResult) |
| } |
| |
| } |
| |
| |
| // LongStyle |
| // locale stringFromDate example |
| // ------ -------------- ----------------- |
| // en_US MMMM d, y 'at' h:mm:ss a zzz December 25, 2015 at 12:00:00 AM GMT |
| func test_dateStyleLong() { |
| |
| let timestamps = [ |
| -31536000 : "January 1, 1969 at 12:00:00 AM GMT" , 0.0 : "January 1, 1970 at 12:00:00 AM GMT", 31536000 : "January 1, 1971 at 12:00:00 AM GMT", |
| 2145916800 : "January 1, 2038 at 12:00:00 AM GMT", 1456272000 : "February 24, 2016 at 12:00:00 AM GMT", 1456358399 : "February 24, 2016 at 11:59:59 PM GMT", |
| 1452574638 : "January 12, 2016 at 4:57:18 AM GMT", 1455685038 : "February 17, 2016 at 4:57:18 AM GMT", 1458622638 : "March 22, 2016 at 4:57:18 AM GMT", |
| 1459745838 : "April 4, 2016 at 4:57:18 AM GMT", 1462597038 : "May 7, 2016 at 4:57:18 AM GMT", 1465534638 : "June 10, 2016 at 4:57:18 AM GMT", |
| 1469854638 : "July 30, 2016 at 4:57:18 AM GMT", 1470718638 : "August 9, 2016 at 4:57:18 AM GMT", 1473915438 : "September 15, 2016 at 4:57:18 AM GMT", |
| 1477285038 : "October 24, 2016 at 4:57:18 AM GMT", 1478062638 : "November 2, 2016 at 4:57:18 AM GMT", 1482641838 : "December 25, 2016 at 4:57:18 AM GMT" |
| ] |
| |
| let f = DateFormatter() |
| f.dateStyle = .long |
| f.timeStyle = .long |
| f.timeZone = TimeZone(identifier: DEFAULT_TIMEZONE) |
| f.locale = Locale(identifier: DEFAULT_LOCALE) |
| |
| for (timestamp, stringResult) in timestamps { |
| |
| let testDate = Date(timeIntervalSince1970: timestamp) |
| let sf = f.string(from: testDate) |
| |
| XCTAssertEqual(sf, stringResult) |
| } |
| |
| } |
| |
| // FullStyle |
| // locale stringFromDate example |
| // ------ -------------- ------------------------- |
| // en_US EEEE, MMMM d, y 'at' h:mm:ss a zzzz Friday, December 25, 2015 at 12:00:00 AM Greenwich Mean Time |
| func test_dateStyleFull() { |
| |
| #if os(macOS) // timestyle .full is currently broken on Linux, the timezone should be 'Greenwich Mean Time' not 'GMT' |
| let timestamps: [TimeInterval:String] = [ |
| // Negative time offsets are still buggy on macOS |
| -31536000 : "Wednesday, January 1, 1969 at 12:00:00 AM GMT", 0.0 : "Thursday, January 1, 1970 at 12:00:00 AM Greenwich Mean Time", |
| 31536000 : "Friday, January 1, 1971 at 12:00:00 AM Greenwich Mean Time", 2145916800 : "Friday, January 1, 2038 at 12:00:00 AM Greenwich Mean Time", |
| 1456272000 : "Wednesday, February 24, 2016 at 12:00:00 AM Greenwich Mean Time", 1456358399 : "Wednesday, February 24, 2016 at 11:59:59 PM Greenwich Mean Time", |
| 1452574638 : "Tuesday, January 12, 2016 at 4:57:18 AM Greenwich Mean Time", 1455685038 : "Wednesday, February 17, 2016 at 4:57:18 AM Greenwich Mean Time", |
| 1458622638 : "Tuesday, March 22, 2016 at 4:57:18 AM Greenwich Mean Time", 1459745838 : "Monday, April 4, 2016 at 4:57:18 AM Greenwich Mean Time", |
| 1462597038 : "Saturday, May 7, 2016 at 4:57:18 AM Greenwich Mean Time", 1465534638 : "Friday, June 10, 2016 at 4:57:18 AM Greenwich Mean Time", |
| 1469854638 : "Saturday, July 30, 2016 at 4:57:18 AM Greenwich Mean Time", 1470718638 : "Tuesday, August 9, 2016 at 4:57:18 AM Greenwich Mean Time", |
| 1473915438 : "Thursday, September 15, 2016 at 4:57:18 AM Greenwich Mean Time", 1477285038 : "Monday, October 24, 2016 at 4:57:18 AM Greenwich Mean Time", |
| 1478062638 : "Wednesday, November 2, 2016 at 4:57:18 AM Greenwich Mean Time", 1482641838 : "Sunday, December 25, 2016 at 4:57:18 AM Greenwich Mean Time" |
| ] |
| |
| let f = DateFormatter() |
| f.dateStyle = .full |
| f.timeStyle = .full |
| f.timeZone = TimeZone(identifier: DEFAULT_TIMEZONE) |
| f.locale = Locale(identifier: DEFAULT_LOCALE) |
| |
| for (timestamp, stringResult) in timestamps { |
| |
| let testDate = Date(timeIntervalSince1970: timestamp) |
| let sf = f.string(from: testDate) |
| |
| XCTAssertEqual(sf, stringResult) |
| } |
| #endif |
| } |
| |
| // Custom Style |
| // locale stringFromDate example |
| // ------ -------------- ------------------------- |
| // en_US EEEE, MMMM d, y 'at' hh:mm:ss a zzzz Friday, December 25, 2015 at 12:00:00 AM Greenwich Mean Time |
| func test_customDateFormat() { |
| let timestamps = [ |
| // Negative time offsets are still buggy on macOS |
| -31536000 : "Wednesday, January 1, 1969 at 12:00:00 AM GMT", 0.0 : "Thursday, January 1, 1970 at 12:00:00 AM Greenwich Mean Time", |
| 31536000 : "Friday, January 1, 1971 at 12:00:00 AM Greenwich Mean Time", 2145916800 : "Friday, January 1, 2038 at 12:00:00 AM Greenwich Mean Time", |
| 1456272000 : "Wednesday, February 24, 2016 at 12:00:00 AM Greenwich Mean Time", 1456358399 : "Wednesday, February 24, 2016 at 11:59:59 PM Greenwich Mean Time", |
| 1452574638 : "Tuesday, January 12, 2016 at 04:57:18 AM Greenwich Mean Time", 1455685038 : "Wednesday, February 17, 2016 at 04:57:18 AM Greenwich Mean Time", |
| 1458622638 : "Tuesday, March 22, 2016 at 04:57:18 AM Greenwich Mean Time", 1459745838 : "Monday, April 4, 2016 at 04:57:18 AM Greenwich Mean Time", |
| 1462597038 : "Saturday, May 7, 2016 at 04:57:18 AM Greenwich Mean Time", 1465534638 : "Friday, June 10, 2016 at 04:57:18 AM Greenwich Mean Time", |
| 1469854638 : "Saturday, July 30, 2016 at 04:57:18 AM Greenwich Mean Time", 1470718638 : "Tuesday, August 9, 2016 at 04:57:18 AM Greenwich Mean Time", |
| 1473915438 : "Thursday, September 15, 2016 at 04:57:18 AM Greenwich Mean Time", 1477285038 : "Monday, October 24, 2016 at 04:57:18 AM Greenwich Mean Time", |
| 1478062638 : "Wednesday, November 2, 2016 at 04:57:18 AM Greenwich Mean Time", 1482641838 : "Sunday, December 25, 2016 at 04:57:18 AM Greenwich Mean Time" |
| ] |
| |
| let f = DateFormatter() |
| f.timeZone = TimeZone(identifier: DEFAULT_TIMEZONE) |
| f.locale = Locale(identifier: DEFAULT_LOCALE) |
| |
| #if os(macOS) // timestyle zzzz is currently broken on Linux |
| f.dateFormat = "EEEE, MMMM d, y 'at' hh:mm:ss a zzzz" |
| for (timestamp, stringResult) in timestamps { |
| |
| let testDate = Date(timeIntervalSince1970: timestamp) |
| let sf = f.string(from: testDate) |
| |
| XCTAssertEqual(sf, stringResult) |
| } |
| #endif |
| |
| let quarterTimestamps: [Double : String] = [ |
| 1451679712 : "1", 1459542112 : "2", 1467404512 : "3", 1475353312 : "4" |
| ] |
| |
| f.dateFormat = "Q" |
| |
| for (timestamp, stringResult) in quarterTimestamps { |
| let testDate = Date(timeIntervalSince1970: timestamp) |
| let sf = f.string(from: testDate) |
| |
| XCTAssertEqual(sf, stringResult) |
| } |
| |
| // Check .dateFormat resets when style changes |
| let testDate = Date(timeIntervalSince1970: 1457738454) |
| |
| // Fails on High Sierra |
| //f.dateStyle = .medium |
| //f.timeStyle = .medium |
| //XCTAssertEqual(f.string(from: testDate), "Mar 11, 2016, 11:20:54 PM") |
| //XCTAssertEqual(f.dateFormat, "MMM d, y, h:mm:ss a") |
| |
| f.dateFormat = "dd-MM-yyyy" |
| XCTAssertEqual(f.string(from: testDate), "11-03-2016") |
| |
| } |
| |
| func test_setLocalizedDateFormatFromTemplate() { |
| let locale = Locale(identifier: DEFAULT_LOCALE) |
| let template = "EEEE MMMM d y hhmmss a zzzz" |
| |
| let f = DateFormatter() |
| f.locale = locale |
| f.setLocalizedDateFormatFromTemplate(template) |
| |
| let dateFormat = DateFormatter.dateFormat(fromTemplate: template, options: 0, locale: locale) |
| XCTAssertEqual(f.dateFormat, dateFormat) |
| } |
| |
| func test_dateFormatString() { |
| let f = DateFormatter() |
| f.timeZone = TimeZone(abbreviation: DEFAULT_TIMEZONE) |
| |
| //.full cases have been commented out as they're not working correctly on Linux |
| let formats: [String: (DateFormatter.Style, DateFormatter.Style)] = [ |
| "": (.none, .none), |
| "h:mm a": (.none, .short), |
| "h:mm:ss a": (.none, .medium), |
| "h:mm:ss a z": (.none, .long), |
| // "h:mm:ss a zzzz": (.none, .full), |
| "M/d/yy": (.short, .none), |
| "M/d/yy, h:mm a": (.short, .short), |
| "M/d/yy, h:mm:ss a": (.short, .medium), |
| "M/d/yy, h:mm:ss a z": (.short, .long), |
| // "M/d/yy, h:mm:ss a zzzz": (.short, .full), |
| "MMM d, y": (.medium, .none), |
| //These tests currently fail, there seems to be a difference in behavior in the CoreFoundation methods called to construct the format strings. |
| // "MMM d, y 'at' h:mm a": (.medium, .short), |
| // "MMM d, y 'at' h:mm:ss a": (.medium, .medium), |
| // "MMM d, y 'at' h:mm:ss a z": (.medium, .long), |
| // "MMM d, y 'at' h:mm:ss a zzzz": (.medium, .full), |
| "MMMM d, y": (.long, .none), |
| "MMMM d, y 'at' h:mm a": (.long, .short), |
| "MMMM d, y 'at' h:mm:ss a": (.long, .medium), |
| "MMMM d, y 'at' h:mm:ss a z": (.long, .long), |
| // "MMMM d, y 'at' h:mm:ss a zzzz": (.long, .full), |
| // "EEEE, MMMM d, y": (.full, .none), |
| // "EEEE, MMMM d, y 'at' h:mm a": (.full, .short), |
| // "EEEE, MMMM d, y 'at' h:mm:ss a": (.full, .medium), |
| // "EEEE, MMMM d, y 'at' h:mm:ss a z": (.full, .long), |
| // "EEEE, MMMM d, y 'at' h:mm:ss a zzzz": (.full, .full), |
| ] |
| |
| for (dateFormat, styles) in formats { |
| f.dateStyle = styles.0 |
| f.timeStyle = styles.1 |
| |
| XCTAssertEqual(f.dateFormat, dateFormat) |
| } |
| } |
| |
| 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_setTimeZone() { |
| // Test two different time zones. Should ensure that if one |
| // happens to be TimeZone.current, we still get a valid test. |
| let newYork = TimeZone(identifier: "America/New_York")! |
| let losAngeles = TimeZone(identifier: "America/Los_Angeles")! |
| |
| XCTAssertNotEqual(newYork, losAngeles) |
| |
| // Case 1: New York |
| let f = DateFormatter() |
| f.timeZone = newYork |
| XCTAssertEqual(f.timeZone, newYork) |
| |
| // Case 2: Los Angeles |
| f.timeZone = losAngeles |
| XCTAssertEqual(f.timeZone, losAngeles) |
| } |
| |
| func test_expectedTimeZone() { |
| let newYork = TimeZone(identifier: "America/New_York")! |
| let losAngeles = TimeZone(identifier: "America/Los_Angeles")! |
| |
| XCTAssertNotEqual(newYork, losAngeles) |
| |
| let now = Date() |
| |
| let f = DateFormatter() |
| f.dateFormat = "z" |
| f.locale = Locale(identifier: "en_US_POSIX") |
| |
| // Case 1: TimeZone.current |
| // This case can catch some issues that cause TimeZone.current to be |
| // treated like GMT, but it doesn't work if TimeZone.current is GMT. |
| // If you do find an issue like this caused by this first case, |
| // it would benefit from a more specific test that fails when |
| // TimeZone.current is GMT as well. |
| // (ex. TestTimeZone.test_systemTimeZoneName) |
| |
| // Disabled because of: https://bugs.swift.org/browse/SR-8994 |
| // f.timeZone = TimeZone.current |
| // XCTAssertEqual(f.string(from: now), TimeZone.current.abbreviation()) |
| |
| // Case 2: New York |
| f.timeZone = newYork |
| XCTAssertEqual(f.string(from: now), newYork.abbreviation()) |
| |
| // Case 3: Los Angeles |
| f.timeZone = losAngeles |
| XCTAssertEqual(f.string(from: now), losAngeles.abbreviation()) |
| } |
| |
| func test_dateFrom() throws { |
| let formatter = DateFormatter() |
| formatter.timeZone = TimeZone(identifier: "UTC") |
| formatter.dateFormat = "yyyy-MM-dd" |
| |
| XCTAssertNil(formatter.date(from: "2018-03-09T10:25:16+01:00")) |
| let d1 = try XCTUnwrap(formatter.date(from: "2018-03-09")) |
| XCTAssertEqual(d1.description, "2018-03-09 00:00:00 +0000") |
| |
| formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" |
| XCTAssertNil(formatter.date(from: "2018-03-09")) |
| let d2 = try XCTUnwrap(formatter.date(from: "2018-03-09T10:25:16+01:00")) |
| XCTAssertEqual(d2.description, "2018-03-09 09:25:16 +0000") |
| } |
| |
| func test_dateParseAndFormatWithJapaneseCalendar() throws { |
| let formatter = DateFormatter() |
| |
| formatter.locale = Locale(identifier: "ja_JP") |
| formatter.calendar = Calendar(identifier: .japanese) |
| formatter.dateFormat = "Gy年M月dd日 HH:mm" |
| formatter.timeZone = TimeZone(abbreviation: "JST") |
| |
| // parse test |
| let parsed = formatter.date(from: "平成31年4月30日 23:10") |
| XCTAssertEqual(parsed?.timeIntervalSince1970, 1556633400) // April 30, 2019, 11:10 PM (JST) |
| |
| // format test |
| let dateString = formatter.string(from: Date(timeIntervalSince1970: 1556633400)) // April 30, 2019, 11:10 PM (JST) |
| XCTAssertEqual(dateString, "平成31年4月30日 23:10") |
| } |
| |
| func test_orderOfPropertySetters() throws { |
| |
| // This produces a .count factorial number of arrays |
| func combinations<T>(of a: [T]) -> [[T]] { |
| precondition(!a.isEmpty) |
| if a.count == 1 { return [a] } |
| if a.count == 2 { return [ [a[0], a[1]], [ a[1], a[0]] ] } |
| |
| var result: [[T]] = [] |
| |
| for idx in a.startIndex..<a.endIndex { |
| let x = a[idx] |
| var b: [T] = a |
| b.remove(at: idx) |
| |
| for var c in combinations(of: b) { |
| c.append(x) |
| result.append(c) |
| } |
| } |
| return result |
| } |
| |
| let formatter = DateFormatter() |
| formatter.timeZone = TimeZone(identifier: "CET") |
| formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" |
| let date = try XCTUnwrap(formatter.date(from: "2019-05-05T12:52:10")) |
| |
| let applySettings: [(String, (DateFormatter) -> Void)] = |
| [(".timeZone", { |
| $0.timeZone = TimeZone(identifier: "Europe/Oslo") |
| }), |
| (".calendar", { |
| $0.calendar = Calendar(identifier: .gregorian) |
| }), |
| (".locale", { |
| $0.locale = Locale(identifier: "nb") |
| }), |
| (".dateStyle", { |
| $0.dateStyle = .medium |
| }), |
| (".timeStyle", { |
| $0.timeStyle = .medium |
| }) |
| ] |
| |
| // Test all of the combinations of setting the properties produces the same output |
| let expected = "5. mai 2019, 12:52:10" |
| for settings in combinations(of: applySettings) { |
| let f = DateFormatter() |
| settings.forEach { $0.1(f) } |
| XCTAssertEqual(f.dateFormat, "d. MMM y, HH:mm:ss") |
| let formattedString = f.string(from: date) |
| if formattedString != expected { |
| let applied = settings.map { $0.0 }.joined(separator: ",") |
| XCTFail("\(formattedString) != \(expected) using settings applied in order \(applied)") |
| } |
| } |
| } |
| } |