| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2018 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 TestNSCalendar: XCTestCase { |
| func test_initWithCalendarIdentifier() { |
| var calMaybe = NSCalendar(calendarIdentifier: NSCalendar.Identifier("Not a calendar")) |
| XCTAssertNil(calMaybe) |
| |
| calMaybe = NSCalendar(calendarIdentifier: .chinese) |
| guard let cal = calMaybe else { |
| XCTFail(); return |
| } |
| |
| XCTAssertEqual(cal.calendarIdentifier, NSCalendar.Identifier.chinese) |
| } |
| |
| func test_calendarWithIdentifier() { |
| var calMaybe = NSCalendar(identifier: NSCalendar.Identifier("Not a calendar")) |
| XCTAssertNil(calMaybe) |
| |
| calMaybe = NSCalendar(identifier: .chinese) |
| guard let cal = calMaybe else { |
| XCTFail(); return |
| } |
| |
| XCTAssertEqual(cal.calendarIdentifier, NSCalendar.Identifier.chinese) |
| } |
| |
| func test_calendarOptions() { |
| let allOptions: [NSCalendar.Options] = [.matchStrictly, .searchBackwards, .matchPreviousTimePreservingSmallerUnits, .matchNextTimePreservingSmallerUnits, .matchNextTime, .matchFirst, .matchLast] |
| |
| for (i, option) in allOptions.enumerated() { |
| var otherOptions: NSCalendar.Options.RawValue = 0 |
| |
| for (j, otherOption) in allOptions.enumerated() { |
| if (i != j) { |
| otherOptions |= otherOption.rawValue |
| } |
| } |
| |
| XCTAssertEqual(0, (option.rawValue & otherOptions), "Options should be exclusive") |
| } |
| } |
| |
| func test_isEqualWithDifferentWaysToCreateCalendar() throws { |
| let date = Date(timeIntervalSinceReferenceDate: 497973600) // 2016-10-12 07:00:00 +0000; |
| |
| let gregorianCalendar = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| let gregorianCalendar2 = try XCTUnwrap(gregorianCalendar.components(.calendar, from: date).calendar) as NSCalendar |
| |
| XCTAssertEqual(gregorianCalendar, gregorianCalendar2) |
| |
| let timeZone = try XCTUnwrap(TimeZone(identifier: "Antarctica/Vostok")) |
| gregorianCalendar.timeZone = timeZone |
| let gregorianCalendar3 = try XCTUnwrap(gregorianCalendar.components(.calendar, from: date).calendar) as NSCalendar |
| |
| XCTAssertEqual(gregorianCalendar, gregorianCalendar3) |
| } |
| |
| func test_isEqual() throws { |
| let testCal1 = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| let testCal2 = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| XCTAssertEqual(testCal1, testCal2) |
| |
| testCal2.timeZone = try XCTUnwrap(TimeZone(identifier: "Antarctica/Vostok")) |
| testCal2.locale = Locale(identifier: "ru_RU") |
| testCal2.firstWeekday += 1 |
| testCal2.minimumDaysInFirstWeek += 1 |
| XCTAssertNotEqual(testCal1, testCal2) |
| |
| let testCal3 = try XCTUnwrap(NSCalendar(calendarIdentifier: .chinese)) |
| XCTAssertNotEqual(testCal1, testCal3) |
| } |
| |
| func test_isEqualCurrentCalendar() { |
| let testCal1 = NSCalendar.current as NSCalendar |
| let testCal2 = NSCalendar.current as NSCalendar |
| XCTAssertEqual(testCal1, testCal2) |
| XCTAssert(testCal1 !== testCal2) |
| |
| XCTAssertNotEqual(testCal1.firstWeekday, 4) |
| testCal1.firstWeekday = 4 |
| XCTAssertNotEqual(testCal1, testCal2) |
| } |
| |
| func test_isEqualAutoUpdatingCurrentCalendar() { |
| let testCal1 = NSCalendar.autoupdatingCurrent as NSCalendar |
| let testCal2 = NSCalendar.autoupdatingCurrent as NSCalendar |
| XCTAssertEqual(testCal1, testCal2) |
| XCTAssert(testCal1 !== testCal2) |
| |
| XCTAssertNotEqual(testCal1.firstWeekday, 4) |
| testCal1.firstWeekday = 4 |
| XCTAssertNotEqual(testCal1, testCal2) |
| } |
| |
| func test_copy() throws { |
| let cal = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| let calCopy = try XCTUnwrap((cal.copy() as? NSCalendar)) |
| XCTAssertEqual(cal, calCopy) |
| XCTAssert(cal !== calCopy) |
| } |
| |
| func test_copyCurrentCalendar() throws { |
| let cal = NSCalendar.current as NSCalendar |
| let calCopy = try XCTUnwrap((cal.copy() as? NSCalendar)) |
| XCTAssertEqual(cal, calCopy) |
| XCTAssert(cal !== calCopy) |
| } |
| |
| // MARK: API Method Tests |
| |
| let timeIntervalsNext50Months: [TimeInterval] = [ |
| 349776000, // 2012-02-01 08:00:00 +0000 |
| 352281600, // 2012-03-01 08:00:00 +0000 |
| 354956400, // 2012-04-01 07:00:00 +0000 |
| 357548400, // 2012-05-01 07:00:00 +0000 |
| 360226800, // 2012-06-01 07:00:00 +0000 |
| 362818800, // 2012-07-01 07:00:00 +0000 |
| 365497200, // 2012-08-01 07:00:00 +0000 |
| 368175600, // 2012-09-01 07:00:00 +0000 |
| 370767600, // 2012-10-01 07:00:00 +0000 |
| 373446000, // 2012-11-01 07:00:00 +0000 |
| 376041600, // 2012-12-01 08:00:00 +0000 |
| 378720000, // 2013-01-01 08:00:00 +0000 |
| 381398400, // 2013-02-01 08:00:00 +0000 |
| 383817600, // 2013-03-01 08:00:00 +0000 |
| 386492400, // 2013-04-01 07:00:00 +0000 |
| 389084400, // 2013-05-01 07:00:00 +0000 |
| 391762800, // 2013-06-01 07:00:00 +0000 |
| 394354800, // 2013-07-01 07:00:00 +0000 |
| 397033200, // 2013-08-01 07:00:00 +0000 |
| 399711600, // 2013-09-01 07:00:00 +0000 |
| 402303600, // 2013-10-01 07:00:00 +0000 |
| 404982000, // 2013-11-01 07:00:00 +0000 |
| 407577600, // 2013-12-01 08:00:00 +0000 |
| 410256000, // 2014-01-01 08:00:00 +0000 |
| 412934400, // 2014-02-01 08:00:00 +0000 |
| 415353600, // 2014-03-01 08:00:00 +0000 |
| 418028400, // 2014-04-01 07:00:00 +0000 |
| 420620400, // 2014-05-01 07:00:00 +0000 |
| 423298800, // 2014-06-01 07:00:00 +0000 |
| 425890800, // 2014-07-01 07:00:00 +0000 |
| 428569200, // 2014-08-01 07:00:00 +0000 |
| 431247600, // 2014-09-01 07:00:00 +0000 |
| 433839600, // 2014-10-01 07:00:00 +0000 |
| 436518000, // 2014-11-01 07:00:00 +0000 |
| 439113600, // 2014-12-01 08:00:00 +0000 |
| 441792000, // 2015-01-01 08:00:00 +0000 |
| 444470400, // 2015-02-01 08:00:00 +0000 |
| 446889600, // 2015-03-01 08:00:00 +0000 |
| 449564400, // 2015-04-01 07:00:00 +0000 |
| 452156400, // 2015-05-01 07:00:00 +0000 |
| 454834800, // 2015-06-01 07:00:00 +0000 |
| 457426800, // 2015-07-01 07:00:00 +0000 |
| 460105200, // 2015-08-01 07:00:00 +0000 |
| 462783600, // 2015-09-01 07:00:00 +0000 |
| 465375600, // 2015-10-01 07:00:00 +0000 |
| 468054000, // 2015-11-01 07:00:00 +0000 |
| 470649600, // 2015-12-01 08:00:00 +0000 |
| 473328000, // 2016-01-01 08:00:00 +0000 |
| 476006400, // 2016-02-01 08:00:00 +0000 |
| 478512000, // 2016-03-01 08:00:00 +0000 |
| ]; |
| |
| func test_next50MonthsFromDate() throws { |
| let calendar = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| calendar.timeZone = try XCTUnwrap(TimeZone(identifier: "America/Los_Angeles")) |
| |
| let startDate = Date(timeIntervalSinceReferenceDate: 347113850) // 2012-01-01 12:30:50 +0000 |
| |
| let expectedDates = timeIntervalsNext50Months.map { Date(timeIntervalSinceReferenceDate: $0) } |
| |
| var count = 0 |
| var resultDates: [Date] = [] |
| let components = NSDateComponents() |
| components.day = 1 |
| |
| calendar.enumerateDates(startingAfter: startDate, matching: components as DateComponents, options: .matchNextTime) { (date, exactMatch, stop) in |
| count += 1 |
| if count > expectedDates.count { |
| stop.pointee = true |
| return |
| } |
| |
| guard let date = date else { |
| XCTFail() |
| stop.pointee = true |
| return |
| } |
| |
| resultDates.append(date) |
| } |
| |
| XCTAssertEqual(expectedDates, resultDates) |
| } |
| |
| let iterableCalendarUnits: [NSCalendar.Unit] = [ |
| .era, |
| .year, |
| .month, |
| .day, |
| .hour, |
| .minute, |
| .second, |
| .weekday, |
| .weekdayOrdinal, |
| .quarter, |
| .weekOfMonth, |
| .weekOfYear, |
| .yearForWeekOfYear, |
| .nanosecond, |
| .calendar, |
| .timeZone, |
| ] |
| |
| let allCalendarUnits: NSCalendar.Unit = [ |
| .era, |
| .year, |
| .month, |
| .day, |
| .hour, |
| .minute, |
| .second, |
| .weekday, |
| .weekdayOrdinal, |
| .quarter, |
| .weekOfMonth, |
| .weekOfYear, |
| .yearForWeekOfYear, |
| .nanosecond, |
| .calendar, |
| .timeZone, |
| ] |
| |
| func yieldUnits(in components: NSDateComponents) -> [NSCalendar.Unit] { |
| return iterableCalendarUnits.filter({ (unit) -> Bool in |
| switch unit { |
| case .calendar: |
| return components.calendar != nil |
| case .timeZone: |
| return components.timeZone != nil |
| default: |
| return components.value(forComponent: unit) != NSDateComponentUndefined |
| } |
| }) |
| } |
| |
| func units(in components: NSDateComponents) -> NSCalendar.Unit { |
| return yieldUnits(in: components).reduce([], { (current, toAdd) in |
| var new = current |
| new.insert(toAdd) |
| return new |
| }) |
| } |
| |
| func performTest_dateByAdding(with calendar: NSCalendar, components: NSDateComponents, toAdd secondComponents: NSDateComponents, options: NSCalendar.Options, expected: NSDateComponents, addSingleUnit: Bool) throws { |
| |
| let date = try XCTUnwrap(calendar.date(from: components as DateComponents)) |
| var returnedDate: Date |
| |
| if addSingleUnit { |
| let unit = units(in: secondComponents) |
| let valueToAdd = secondComponents.value(forComponent: unit) |
| |
| returnedDate = try XCTUnwrap(calendar.date(byAdding: unit, value: valueToAdd, to: date, options: options)) |
| } else { |
| returnedDate = try XCTUnwrap(calendar.date(byAdding: secondComponents as DateComponents, to: date, options: options)) |
| } |
| |
| let expectedUnitFlags = units(in: expected) |
| |
| // If the NSDateComponents is being added to with a time zone, we want the result to be in the same time zone. |
| let originalTimeZone = calendar.timeZone |
| let calculationTimeZone = components.timeZone |
| if let calculationTimeZone = calculationTimeZone { |
| calendar.timeZone = calculationTimeZone |
| } |
| |
| let returnedComponents = calendar.components(expectedUnitFlags, from: returnedDate) as NSDateComponents |
| |
| XCTAssertEqual(expected, returnedComponents, "\(calendar.calendarIdentifier) \(components) \(secondComponents) Expected \(expected), but received \(returnedComponents)") |
| |
| if calculationTimeZone != nil { |
| calendar.timeZone = originalTimeZone |
| } |
| } |
| |
| func performTest_componentsFromDateToDate(with calendar: NSCalendar, from fromComponents: NSDateComponents, to toComponents: NSDateComponents, expected: NSDateComponents, options: NSCalendar.Options) throws { |
| let fromDate = try XCTUnwrap(calendar.date(from: fromComponents as DateComponents)) |
| let toDate = try XCTUnwrap(calendar.date(from: toComponents as DateComponents)) |
| |
| let expectedUnitFlags = units(in: expected) |
| let returned = calendar.components(expectedUnitFlags, from: fromDate, to: toDate, options: options) as NSDateComponents |
| XCTAssertEqual(expected, returned, "Expected \(expected), but received \(returned) - from date: \(fromDate) to date: \(toDate)") |
| } |
| |
| func performTest_componentsFromDCToDC(with calendar: NSCalendar, from fromComponents: NSDateComponents, to toComponents: NSDateComponents, expected: NSDateComponents, options: NSCalendar.Options) throws { |
| let expectedUnitFlags = units(in: expected) |
| let returned = calendar.components(expectedUnitFlags, from: fromComponents as DateComponents, to: toComponents as DateComponents, options: options) as NSDateComponents |
| XCTAssertEqual(expected, returned, "Expected \(expected), but received \(returned) - from components: \(fromComponents) to components: \(toComponents)") |
| } |
| |
| func performTest_getComponentsInOtherCalendar(from fromCalendar: NSCalendar, to toCalendar: NSCalendar, from fromComponents: NSDateComponents, expected: NSDateComponents) throws { |
| let originalTZ = fromCalendar.timeZone |
| fromCalendar.timeZone = toCalendar.timeZone |
| |
| let fromDate = try XCTUnwrap(fromCalendar.date(from: fromComponents as DateComponents)) |
| |
| fromCalendar.timeZone = originalTZ |
| |
| let expectedUnitFlags = units(in: expected) |
| let returned = toCalendar.components(expectedUnitFlags, from: fromDate) as NSDateComponents |
| |
| XCTAssertEqual(expected, returned, "Expected \(expected), but received \(returned) - from calendar: \(fromCalendar) to calendar: \(toCalendar) from components: \(fromComponents)") |
| } |
| |
| func test_dateByAddingUnit_withWrapOption() throws { |
| let locale = Locale(identifier: "ar_EG") |
| let calendar = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| let timeZone = try XCTUnwrap(TimeZone(abbreviation: "GMT")) |
| |
| calendar.locale = locale |
| calendar.timeZone = timeZone |
| |
| let date = try self.date(fromFixture: "2013-09-20 23:20:28 +0000") |
| let newDate = try XCTUnwrap(calendar.date(byAdding: .hour, value: 12, to: date, options: .wrapComponents)) |
| XCTAssertEqual(newDate, try self.date(fromFixture: "2013-09-20 11:20:28 +0000")) |
| } |
| |
| func date(fromFixture string: String) throws -> Date { |
| let formatter = DateFormatter() |
| let calendar = Calendar(identifier: .gregorian) |
| |
| formatter.calendar = calendar |
| formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z" |
| formatter.locale = Locale(identifier: "en_US") |
| |
| return try XCTUnwrap(formatter.date(from: string)) |
| } |
| |
| func enumerateTestDates(using block: (NSCalendar, Date, NSDateComponents) throws -> Void) throws { |
| func yield(to block: (NSCalendar, Date, NSDateComponents) throws -> Void, _ element: (calendarIdentifier: NSCalendar.Identifier, localeIdentifier: String, timeZoneName: String, dateString: String)) throws { |
| let calendar = try XCTUnwrap(NSCalendar(calendarIdentifier: element.calendarIdentifier)) |
| let currentCalendar = NSCalendar.current as NSCalendar |
| let autoCalendar = NSCalendar.autoupdatingCurrent as NSCalendar |
| |
| for aCalendar in [calendar, currentCalendar, autoCalendar] { |
| if aCalendar.calendarIdentifier != element.calendarIdentifier { |
| continue |
| } |
| |
| let locale = NSLocale(localeIdentifier: element.localeIdentifier) as Locale |
| let timeZone = try XCTUnwrap(TimeZone(identifier: element.timeZoneName)) |
| calendar.locale = locale |
| calendar.timeZone = timeZone |
| |
| let date = try self.date(fromFixture: element.dateString) |
| let components = calendar.components(self.allCalendarUnits, from: date) as NSDateComponents |
| |
| try block(calendar, date, components) |
| } |
| } |
| |
| try yield(to: block, (.gregorian, "en_US", "America/Edmonton", "1906-09-01 00:33:52 -0700")) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800")) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2016-02-29 06:30:33 -0900")) |
| try yield(to: block, (.hebrew, "he_IL", "Israel", "2018-12-24 05:40:43 +0200")) |
| try yield(to: block, (.hebrew, "he_IL", "Israel", "2019-03-22 09:23:26 +0200")) |
| try yield(to: block, (.buddhist, "es_MX", "America/Cancun", "2022-10-26 23:05:34 -0500")) |
| try yield(to: block, (.buddhist, "es_MX", "America/Cancun", "2014-10-22 07:13:00 -0500")) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2013-08-23 06:09:01 +0900")) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2014-11-23 05:34:30 +0900")) |
| try yield(to: block, (.persian, "ps_AF", "Asia/Kabul", "2013-07-18 20:55:06 +0430")) |
| try yield(to: block, (.persian, "ps_AF", "Asia/Kabul", "2015-09-21 23:21:45 +0430")) |
| try yield(to: block, (.coptic, "ar_EG", "Africa/Cairo", "2013-12-22 19:49:15 +0200")) |
| try yield(to: block, (.coptic, "ar_EG", "Africa/Cairo", "2015-03-14 17:36:20 +0200")) |
| try yield(to: block, (.ethiopicAmeteMihret, "am_ET", "Africa/Addis_Ababa", "2014-01-31 10:10:33 +0300")) |
| try yield(to: block, (.ethiopicAmeteMihret, "am_ET", "Africa/Addis_Ababa", "2013-07-19 13:05:16 +0300")) |
| try yield(to: block, (.ethiopicAmeteAlem, "am_ET", "Africa/Addis_Ababa", "2015-02-28 16:34:34 +0300")) |
| try yield(to: block, (.ethiopicAmeteAlem, "am_ET", "Africa/Addis_Ababa", "2017-07-19 15:25:59 +0300")) |
| try yield(to: block, (.islamic, "ar_SA", "Asia/Riyadh", "2015-06-04 19:28:36 +0300")) |
| try yield(to: block, (.islamic, "ar_SA", "Asia/Riyadh", "2015-05-21 21:47:39 +0300")) |
| try yield(to: block, (.islamicCivil, "ar_SA", "Asia/Riyadh", "2002-05-05 22:44:18 +0300")) |
| try yield(to: block, (.islamicCivil, "ar_SA", "Asia/Riyadh", "2015-11-20 02:21:09 +0300")) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2019-04-12 01:12:10 +0800")) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2015-04-02 07:13:22 +0800")) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-16 06:12:10 +0800")) |
| } |
| |
| func test_getEra_year_month_day_fromDate() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| var era = 0, year = 0, month = 0, day = 0 |
| calendar.getEra(&era, year: &year, month: &month, day: &day, from: date) |
| |
| XCTAssertEqual(era, components.era) |
| XCTAssertEqual(year, components.year) |
| XCTAssertEqual(month, components.month) |
| XCTAssertEqual(day, components.day) |
| } |
| } |
| |
| func test_getEra_yearForWeekOfYear_weekOfYear_weekday_fromDate() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| var era = 0, yearForWeekOfYear = 0, weekOfYear = 0, weekday = 0 |
| calendar.getEra(&era, yearForWeekOfYear: &yearForWeekOfYear, weekOfYear: &weekOfYear, weekday: &weekday, from: date) |
| |
| XCTAssertEqual(era, components.era) |
| XCTAssertEqual(yearForWeekOfYear, components.yearForWeekOfYear) |
| XCTAssertEqual(weekOfYear, components.weekOfYear) |
| XCTAssertEqual(weekday, components.weekday) |
| } |
| } |
| |
| func test_getHour_minute_second_nanoseconds_fromDate() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| var hour = 0, minute = 0, second = 0, nanosecond = 0 |
| calendar.getHour(&hour, minute: &minute, second: &second, nanosecond: &nanosecond, from: date) |
| |
| XCTAssertEqual(hour, components.hour) |
| XCTAssertEqual(minute, components.minute) |
| XCTAssertEqual(second, components.second) |
| XCTAssertEqual(nanosecond, components.nanosecond) |
| } |
| } |
| |
| func test_component_fromDate() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| for unit in iterableCalendarUnits { |
| if unit == .calendar || unit == .timeZone { |
| continue |
| } |
| |
| let value = calendar.component(unit, from: date) |
| let expectedValue = components.value(forComponent: unit) |
| |
| XCTAssertEqual(expectedValue, value) |
| } |
| } |
| } |
| |
| func test_dateWithYear_month_day_hour_minute_second_nanosecond() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| let returnedDate = try XCTUnwrap(calendar.date(era: components.era, year: components.year, month: components.month, day: components.day, hour: components.hour, minute: components.minute, second: components.second, nanosecond: components.nanosecond)) |
| |
| let interval = date.timeIntervalSince(returnedDate) |
| XCTAssertEqual(fabs(interval), 0, accuracy: 0.0000001) |
| } |
| } |
| |
| func test_dateWithYearForWeekOfYear_weekOfYear_weekday_hour_minute_second_nanosecond() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| // Era is defined to be in the current era, so the below can only work for dates that are in the current era. |
| if components.era != calendar.components(.era, from: Date()).era { |
| return |
| } |
| if (calendar.calendarIdentifier == .chinese) { |
| // chinese calendar does not work for yearForWeekOfYear |
| return; |
| } |
| |
| let returnedDate = try XCTUnwrap(calendar.date(era: components.era, yearForWeekOfYear: components.yearForWeekOfYear, weekOfYear: components.weekOfYear, weekday: components.weekday, hour: components.hour, minute: components.minute, second: components.second, nanosecond: components.nanosecond)) |
| |
| let interval = date.timeIntervalSince(returnedDate) |
| XCTAssertEqual(fabs(interval), 0, accuracy: 0.0000001) |
| } |
| } |
| |
| func enumerateTestDatesWithStartOfDay(using block: (NSCalendar, Date, Date) throws -> Void) throws { |
| func yield(to block: (NSCalendar, Date, Date) throws -> Void, _ element: (calendarIdentifier: NSCalendar.Identifier, localeIdentifier: String, timeZoneName: String, dateString: String, startOfDayDateString: String)) throws { |
| let calendar = try XCTUnwrap(NSCalendar(calendarIdentifier: element.calendarIdentifier)) |
| let currentCalendar = NSCalendar.current as NSCalendar |
| let autoCalendar = NSCalendar.autoupdatingCurrent as NSCalendar |
| |
| for aCalendar in [calendar, currentCalendar, autoCalendar] { |
| if aCalendar.calendarIdentifier != element.calendarIdentifier { |
| continue |
| } |
| |
| let locale = NSLocale(localeIdentifier: element.localeIdentifier) as Locale |
| let timeZone = try XCTUnwrap(TimeZone(identifier: element.timeZoneName)) |
| calendar.locale = locale |
| calendar.timeZone = timeZone |
| |
| let date = try self.date(fromFixture: element.dateString) |
| let startOfDay = try self.date(fromFixture: element.startOfDayDateString) |
| |
| try block(calendar, date, startOfDay) |
| } |
| } |
| |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2013-03-26 10:04:16 -0700", "2013-03-26 00:00:00 -0700")) |
| try yield(to: block, (.gregorian, "pt_BR", "Brazil/East", "2013-10-20 13:10:20 -0200", "2013-10-20 01:00:00 -0200")) // DST jump forward at midnight |
| try yield(to: block, (.gregorian, "pt_BR", "Brazil/East", "2014-02-15 23:59:59 -0300", "2014-02-15 00:00:00 -0200")) // DST jump backward |
| } |
| |
| func test_startOfDayForDate() throws { |
| try enumerateTestDatesWithStartOfDay() { (calendar, date, startOfDay) in |
| let resultDate = calendar.startOfDay(for: date) |
| XCTAssertEqual(startOfDay, resultDate) |
| } |
| } |
| |
| func test_componentsInTimeZone_fromDate() throws { |
| try enumerateTestDates() { (calendar, date, components) in |
| let calendarWithoutTimeZone = try XCTUnwrap(NSCalendar(identifier: calendar.calendarIdentifier)) |
| calendarWithoutTimeZone.locale = calendar.locale |
| |
| let timeZone = calendar.timeZone |
| |
| let returned = calendarWithoutTimeZone.components(in: timeZone, from: date) as NSDateComponents |
| XCTAssertEqual(components, returned) |
| } |
| } |
| |
| func enumerateTestDateComparisons(using block: (NSCalendar, Date, Date, NSCalendar.Unit, ComparisonResult) throws -> Void) throws { |
| func yield(to block: (NSCalendar, Date, Date, NSCalendar.Unit, ComparisonResult) throws -> Void, _ element: (calendarIdentifier: NSCalendar.Identifier, localeIdentifier: String, timeZoneName: String, firstDateString: String, secondDateString: String, granularity: NSCalendar.Unit, expectedResult: ComparisonResult)) throws { |
| let calendar = try XCTUnwrap(NSCalendar(calendarIdentifier: element.calendarIdentifier)) |
| let currentCalendar = NSCalendar.current as NSCalendar |
| let autoCalendar = NSCalendar.autoupdatingCurrent as NSCalendar |
| |
| for aCalendar in [calendar, currentCalendar, autoCalendar] { |
| if aCalendar.calendarIdentifier != element.calendarIdentifier { |
| continue |
| } |
| |
| let locale = NSLocale(localeIdentifier: element.localeIdentifier) as Locale |
| let timeZone = try XCTUnwrap(TimeZone(identifier: element.timeZoneName)) |
| calendar.locale = locale |
| calendar.timeZone = timeZone |
| |
| let firstDate = try self.date(fromFixture: element.firstDateString) |
| let secondDate = try self.date(fromFixture: element.secondDateString) |
| |
| try block(calendar, firstDate, secondDate, element.granularity, element.expectedResult) |
| } |
| } |
| |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800", "2014-09-23 20:11:39 -0800", .year, .orderedSame)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800", "2014-09-23 20:11:39 -0800", .month, .orderedSame)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800", "2014-09-23 20:11:39 -0800", .day, .orderedSame)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800", "2014-09-23 20:11:39 -0800", .hour, .orderedSame)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800", "2014-09-23 20:11:39 -0800", .minute, .orderedSame)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-09-23 20:11:39 -0800", "2014-09-23 20:11:39 -0800", .second, .orderedSame)) |
| |
| // DST fall back |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-11-02 01:30:00 -0700", "2014-11-02 01:30:00 -0800", .day, .orderedSame)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-11-02 01:30:00 -0700", "2014-11-02 01:30:00 -0800", .hour, .orderedAscending)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-11-02 01:30:00 -0700", "2014-11-02 01:30:00 -0800", .minute, .orderedAscending)) |
| try yield(to: block, (.gregorian, "en_US", "America/Los_Angeles", "2014-11-02 01:30:00 -0700", "2014-11-02 01:30:00 -0800", .second, .orderedAscending)) |
| |
| // Chinese leap month. First date is not a leap month, 2nd is. Same day. |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .era, .orderedSame)) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .year, .orderedSame)) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .month, .orderedAscending)) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .day, .orderedAscending)) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .hour, .orderedAscending)) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .minute, .orderedAscending)) |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2014-10-07 21:12:10 +0000", "2014-11-06 21:12:10 +0000", .second, .orderedAscending)) |
| |
| // Different eras. era: 235, year: 23, month: 1, day: 22 vs era: 234, year: 23, month: 1, day: 22 |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .era, .orderedDescending)) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .year, .orderedDescending)) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .month, .orderedDescending)) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .day, .orderedDescending)) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .hour, .orderedDescending)) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .minute, .orderedDescending)) |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2011-01-23 06:12:10 +0900", "1948-01-23 06:12:10 +0900", .second, .orderedDescending)) |
| |
| // Same week and week of year, different non-week year. |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2013-01-04 02:34:56 +0000", .yearForWeekOfYear, .orderedSame)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2013-01-04 02:34:56 +0000", .weekOfYear, .orderedSame)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2013-01-04 02:34:56 +0000", .weekOfMonth, .orderedAscending)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2013-01-04 02:34:56 +0000", .weekday, .orderedAscending)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2013-01-04 02:34:56 +0000", .weekdayOrdinal, .orderedAscending)) |
| |
| // Same non-week year, different week of year |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2012-12-29 02:34:56 +0000", .yearForWeekOfYear, .orderedDescending)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2012-12-29 02:34:56 +0000", .weekOfYear, .orderedDescending)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2012-12-29 02:34:56 +0000", .weekOfMonth, .orderedDescending)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-30 02:34:56 +0000", "2012-12-29 02:34:56 +0000", .weekday, .orderedDescending)) |
| |
| // Same week, different weekday ordinal |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-14 02:34:56 +0000", "2012-12-15 02:34:56 +0000", .weekOfYear, .orderedSame)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-14 02:34:56 +0000", "2012-12-15 02:34:56 +0000", .weekOfMonth, .orderedSame)) |
| try yield(to: block, (.buddhist, "zh-Hans_HK", "Asia/Hong_Kong", "2012-12-14 02:34:56 +0000", "2012-12-15 02:34:56 +0000", .weekdayOrdinal, .orderedAscending)) |
| } |
| |
| func test_compareDate_toDate_toUnitGranularity() throws { |
| try enumerateTestDateComparisons { (calendar, firstDate, secondDate, granularity, result) in |
| let returned = calendar.compare(firstDate, to: secondDate, toUnitGranularity: granularity) |
| |
| XCTAssertEqual(returned, result, "Comparison result should match; expected \(result), got \(returned), when comparing \(firstDate) (\(firstDate.timeIntervalSinceReferenceDate) to \(secondDate) (\(secondDate.timeIntervalSinceReferenceDate) with granularity \(granularity)") |
| } |
| } |
| |
| func test_isDate_equalToDate_toUnitGranularity() throws { |
| try enumerateTestDateComparisons { (calendar, firstDate, secondDate, granularity, result) in |
| let expected = result == .orderedSame |
| let returned = calendar.isDate(firstDate, equalTo: secondDate, toUnitGranularity: granularity) |
| |
| XCTAssertEqual(returned, expected) |
| } |
| } |
| |
| let availableCalendarIdentifiers: [NSCalendar.Identifier] = [ |
| .gregorian, |
| .buddhist, |
| .chinese, |
| .coptic, |
| .ethiopicAmeteMihret, |
| .ethiopicAmeteAlem, |
| .hebrew, |
| .ISO8601, |
| .indian, |
| .islamic, |
| .islamicCivil, |
| .japanese, |
| .persian, |
| .republicOfChina, |
| .islamicTabular, |
| .islamicUmmAlQura, |
| ] |
| |
| func test_isDateInToday() throws { |
| var datesTested: [Date] = [] |
| for identifier in availableCalendarIdentifiers { |
| let calendar = try XCTUnwrap(NSCalendar(identifier: identifier)) |
| |
| var foundDate = false |
| var dateInToday = Date() |
| for _ in 0..<10 { |
| datesTested.append(dateInToday) |
| if calendar.isDateInToday(dateInToday) { |
| foundDate = true |
| break |
| } |
| dateInToday += 1 |
| } |
| |
| XCTAssertTrue(foundDate, "Unable to match any of these dates: \(datesTested)") |
| |
| // Makes sure it doesn't work for other dates: |
| XCTAssertFalse(calendar.isDateInToday(Date.distantPast), "Shouldn't match the distant past") |
| XCTAssertFalse(calendar.isDateInToday(Date.distantFuture), "Shouldn't match the distant future") |
| } |
| } |
| |
| func test_isDateInYesterday() throws { |
| var datesTested: [Date] = [] |
| for identifier in availableCalendarIdentifiers { |
| let calendar = try XCTUnwrap(NSCalendar(identifier: identifier)) |
| |
| var foundDate = false |
| var dateInToday = Date() |
| for _ in 0..<10 { |
| let delta = NSDateComponents() |
| delta.day = -1 |
| let dateInYesterday = try XCTUnwrap(calendar.date(byAdding: delta as DateComponents, to: dateInToday)) |
| |
| datesTested.append(dateInYesterday) |
| if calendar.isDateInYesterday(dateInYesterday) { |
| foundDate = true |
| break |
| } |
| dateInToday += 1 |
| } |
| |
| XCTAssertTrue(foundDate, "Unable to match any of these dates: \(datesTested)") |
| |
| // Makes sure it doesn't work for other dates: |
| XCTAssertFalse(calendar.isDateInYesterday(Date.distantPast), "Shouldn't match the distant past") |
| XCTAssertFalse(calendar.isDateInYesterday(Date.distantFuture), "Shouldn't match the distant future") |
| } |
| } |
| |
| func test_isDateInTomorrow() throws { |
| var datesTested: [Date] = [] |
| for identifier in availableCalendarIdentifiers { |
| let calendar = try XCTUnwrap(NSCalendar(identifier: identifier)) |
| |
| var foundDate = false |
| var dateInToday = Date() |
| for _ in 0..<10 { |
| let delta = NSDateComponents() |
| delta.day = 1 |
| let dateInTomorrow = try XCTUnwrap(calendar.date(byAdding: delta as DateComponents, to: dateInToday)) |
| |
| datesTested.append(dateInTomorrow) |
| if calendar.isDateInTomorrow(dateInTomorrow) { |
| foundDate = true |
| break |
| } |
| dateInToday += 1 |
| } |
| |
| XCTAssertTrue(foundDate, "Unable to match any of these dates: \(datesTested)") |
| |
| // Makes sure it doesn't work for other dates: |
| XCTAssertFalse(calendar.isDateInTomorrow(Date.distantPast), "Shouldn't match the distant past") |
| XCTAssertFalse(calendar.isDateInTomorrow(Date.distantFuture), "Shouldn't match the distant future") |
| } |
| } |
| |
| func enumerateTestWeekends(using block: (NSCalendar, DateInterval) throws -> Void) throws { |
| func yield(to block: (NSCalendar, DateInterval) throws -> Void, _ element: (calendarIdentifier: NSCalendar.Identifier, localeIdentifier: String, timeZoneName: String, firstDateString: String, secondDateString: String)) throws { |
| let calendar = try XCTUnwrap(NSCalendar(calendarIdentifier: element.calendarIdentifier)) |
| |
| let locale = NSLocale(localeIdentifier: element.localeIdentifier) as Locale |
| let timeZone = try XCTUnwrap(TimeZone(identifier: element.timeZoneName)) |
| calendar.locale = locale |
| calendar.timeZone = timeZone |
| |
| let firstDate = try self.date(fromFixture: element.firstDateString) |
| let secondDate = try self.date(fromFixture: element.secondDateString) |
| |
| try block(calendar, DateInterval(start: firstDate, end: secondDate)) |
| } |
| |
| try yield(to: block, (.gregorian, "en_US", "America/Edmonton", "1906-09-01 00:33:52 -0700", "1906-09-03 00:00:00 -0700")) // suprise weekend 1 |
| try yield(to: block, (.gregorian, "en_US", "Asia/Damascus", "2006-04-01 01:00:00 +0300", "2006-04-03 00:00:00 +0300")) // suprise weekend 2 |
| try yield(to: block, (.gregorian, "en_US", "Asia/Tehran", "2014-03-22 01:00:00 +0430", "2014-03-24 00:00:00 +0430")) // suprise weekend 3 |
| try yield(to: block, (.gregorian, "en_US", "Africa/Algiers", "1971-04-24 00:00:00 +0000", "1971-04-26 00:00:00 +0100")) // suprise weekday 1 |
| try yield(to: block, (.gregorian, "en_US", "America/Toronto", "1919-03-29 00:00:00 -0500", "1919-03-31 00:30:00 -0400")) // suprise weekday 2 |
| try yield(to: block, (.gregorian, "en_US", "Europe/Madrid", "1978-04-01 00:00:00 +0100", "1978-04-03 00:00:00 +0200")) // suprise weekday 3 |
| try yield(to: block, (.hebrew, "he_IL", "Israel", "2018-03-23 00:00:00 +0200", "2018-03-25 00:00:00 +0300")) // weekend with DST jump |
| try yield(to: block, (.japanese, "ja_JP", "Asia/Tokyo", "2015-08-22 00:00:00 +0900", "2015-08-24 00:00:00 +0900")) // japanese |
| try yield(to: block, (.persian, "ps_AF", "Asia/Kabul", "2015-03-19 00:00:00 +0430", "2015-03-21 00:00:00 +0430")) // persian |
| try yield(to: block, (.coptic, "ar_EG", "Africa/Cairo", "2015-12-18 00:00:00 +0200", "2015-12-20 00:00:00 +0200")) // coptic |
| try yield(to: block, (.ethiopicAmeteMihret, "am_ET", "Africa/Addis_Ababa", "2015-07-25 00:00:00 +0300", "2015-07-27 00:00:00 +0300")) // ethiopic |
| try yield(to: block, (.ethiopicAmeteAlem, "am_ET", "Africa/Addis_Ababa", "2015-07-25 00:00:00 +0300", "2015-07-27 00:00:00 +0300")) // ethiopic-amete-alem |
| try yield(to: block, (.islamic, "ar_SA", "Asia/Riyadh", "2015-05-29 00:00:00 +0300", "2015-05-31 00:00:00 +0300")) // islamic |
| try yield(to: block, (.islamicCivil, "ar_SA", "Asia/Riyadh", "2015-05-29 00:00:00 +0300", "2015-05-31 00:00:00 +0300")) // islamic-civil |
| try yield(to: block, (.chinese, "zh_CN", "Asia/Hong_Kong", "2015-01-03 00:00:00 +0800", "2015-01-05 00:00:00 +0800")) // chinese |
| } |
| |
| func test_isDateInWeekend() throws { |
| try enumerateTestWeekends() { (calendar, interval) in |
| XCTAssertTrue(calendar.isDateInWeekend(interval.start), "Start date should be in weekend") |
| XCTAssertFalse(calendar.isDateInWeekend(interval.end), "End date should not be in weekend") |
| |
| XCTAssertFalse(calendar.isDateInWeekend(interval.start - 1), "Just before start date should not be in weekend") |
| XCTAssertTrue(calendar.isDateInWeekend(interval.end - 1), "Just before end date should be in weekend") |
| } |
| } |
| |
| func test_rangeOfWeekendStartDate_interval_containingDate() throws { |
| #if !DARWIN_COMPATIBILITY_TESTS // NSCalender range(ofWeekendContaining:) is experimental |
| try enumerateTestWeekends() { (calendar, interval) in |
| let startDateResult = calendar.range(ofWeekendContaining: interval.start) |
| XCTAssertEqual(startDateResult, interval) |
| |
| let endDateResult = calendar.range(ofWeekendContaining: interval.end) |
| XCTAssertNil(endDateResult) |
| |
| let oneSecondBeforeStartResult = calendar.range(ofWeekendContaining: interval.start - 1) |
| XCTAssertNil(oneSecondBeforeStartResult) |
| |
| let oneSecondBeforeEndResult = calendar.range(ofWeekendContaining: interval.end - 1) |
| XCTAssertEqual(oneSecondBeforeEndResult, interval) |
| } |
| #endif |
| } |
| |
| func test_enumerateDatesStartingAfterDate_chineseEra_matchYearOne() throws { |
| let calendar = try XCTUnwrap(NSCalendar(calendarIdentifier: .chinese)) |
| let locale = Locale(identifier: "zh_CN") |
| let timeZone = try XCTUnwrap(TimeZone(identifier: "Asia/Chongqing")) |
| calendar.locale = locale |
| calendar.timeZone = timeZone |
| |
| let startDate = try date(fromFixture: "2013-06-19 15:59:59 +0000") |
| let matchingComponents = NSDateComponents() |
| matchingComponents.year = 1 |
| |
| let expectedDate = try date(fromFixture: "1984-02-01 16:00:00 +0000") |
| var atLeastOnce = false |
| |
| calendar.enumerateDates(startingAfter: startDate, matching: matchingComponents as DateComponents, options: [.matchStrictly, .searchBackwards]) { (date, exactMatch, stop) in |
| atLeastOnce = true |
| if let date = date { |
| XCTAssertEqual(expectedDate, date) |
| XCTAssertTrue(exactMatch) |
| stop.pointee = true |
| } |
| } |
| |
| XCTAssertTrue(atLeastOnce) |
| } |
| |
| struct TimeIntervalQuintuple { |
| var value: (TimeInterval, TimeInterval, TimeInterval, TimeInterval, TimeInterval) = (0, 0, 0, 0, 0) |
| |
| subscript(_ index: Int) -> TimeInterval { |
| switch index { |
| case 0: |
| return value.0 |
| case 1: |
| return value.1 |
| case 2: |
| return value.2 |
| case 3: |
| return value.3 |
| case 4: |
| return value.4 |
| default: |
| fatalError() |
| } |
| } |
| |
| let count = 5 |
| |
| init(_ a: TimeInterval, _ b: TimeInterval, _ c: TimeInterval, _ d: TimeInterval, _ e: TimeInterval) { |
| value = (a, b, c, d, e) |
| } |
| } |
| |
| func test_enumerateDatesStartingAfterDate_ensureStrictlyIncreasingResults_minuteSecondClearing() throws { |
| // When we match a specific hour in date enumeration, we clear out lower units (minute and second). This can cause us to accidentally match the components backwards, when we otherwise wouldn't have (e.g. 2018-02-14 00:00:01 -> 2018-02-14 00:00:00). |
| // This leads us to propose a potential match twice in certain circumstances (when the highest set date component is hour and we're looking for hour 0). |
| // |
| // We want to ensure this never happens, and that all matches are strictly increasing or decreasing in time. |
| let calendar = try XCTUnwrap(NSCalendar(identifier: .gregorian)) |
| calendar.timeZone = try XCTUnwrap(TimeZone(identifier: "America/Los_Angeles")) |
| |
| let reference = try date(fromFixture: "2018-02-13 12:00:00 -0800") |
| let expectations: [(minute: Int, second: Int, results: TimeIntervalQuintuple)] = [ |
| (NSDateComponentUndefined, NSDateComponentUndefined, TimeIntervalQuintuple(540288000, 540374400, 540460800, 540547200, 540633600)), |
| (0 , NSDateComponentUndefined, TimeIntervalQuintuple(540288000, 540374400, 540460800, 540547200, 540633600)), |
| (NSDateComponentUndefined, 0 , TimeIntervalQuintuple(540288000, 540374400, 540460800, 540547200, 540633600)), |
| (0 , 0 , TimeIntervalQuintuple(540288000, 540374400, 540460800, 540547200, 540633600)), |
| ] |
| |
| for expectation in expectations { |
| let matchComponents = NSDateComponents() |
| matchComponents.hour = 0 |
| matchComponents.minute = expectation.minute |
| matchComponents.second = expectation.second |
| |
| var j = 0 |
| calendar.enumerateDates(startingAfter: reference, matching: matchComponents as DateComponents, options: .matchNextTime) { (match, exactMatch, stop) in |
| let expected = Date(timeIntervalSinceReferenceDate: TimeInterval(expectation.results[j])) |
| XCTAssertTrue(exactMatch) |
| XCTAssertEqual(match, expected) |
| |
| j += 1 |
| guard j < expectation.results.count else { |
| stop.pointee = true |
| return |
| } |
| } |
| } |
| } |
| |
| static var allTests: [(String, (TestNSCalendar) -> () throws -> Void)] { |
| return [ |
| ("test_initWithCalendarIdentifier", test_initWithCalendarIdentifier), |
| ("test_calendarWithIdentifier", test_calendarWithIdentifier), |
| ("test_calendarOptions", test_calendarOptions), |
| ("test_isEqualWithDifferentWaysToCreateCalendar", test_isEqualWithDifferentWaysToCreateCalendar), |
| ("test_isEqual", test_isEqual), |
| ("test_isEqualCurrentCalendar", test_isEqualCurrentCalendar), |
| ("test_isEqualAutoUpdatingCurrentCalendar", test_isEqualAutoUpdatingCurrentCalendar), |
| ("test_copy", test_copy), |
| ("test_copyCurrentCalendar", test_copyCurrentCalendar), |
| ("test_next50MonthsFromDate", test_next50MonthsFromDate), |
| ("test_dateByAddingUnit_withWrapOption", test_dateByAddingUnit_withWrapOption), |
| ("test_getEra_year_month_day_fromDate", test_getEra_year_month_day_fromDate), |
| ("test_getEra_yearForWeekOfYear_weekOfYear_weekday_fromDate", test_getEra_yearForWeekOfYear_weekOfYear_weekday_fromDate), |
| ("test_getHour_minute_second_nanoseconds_fromDate", test_getHour_minute_second_nanoseconds_fromDate), |
| ("test_component_fromDate", test_component_fromDate), |
| ("test_dateWithYear_month_day_hour_minute_second_nanosecond", test_dateWithYear_month_day_hour_minute_second_nanosecond), |
| ("test_dateWithYearForWeekOfYear_weekOfYear_weekday_hour_minute_second_nanosecond", test_dateWithYearForWeekOfYear_weekOfYear_weekday_hour_minute_second_nanosecond), |
| ("test_startOfDayForDate", test_startOfDayForDate), |
| ("test_componentsInTimeZone_fromDate", test_componentsInTimeZone_fromDate), |
| ("test_compareDate_toDate_toUnitGranularity", test_compareDate_toDate_toUnitGranularity), |
| ("test_isDate_equalToDate_toUnitGranularity", test_isDate_equalToDate_toUnitGranularity), |
| ("test_isDateInToday", test_isDateInToday), |
| ("test_isDateInYesterday", test_isDateInYesterday), |
| ("test_isDateInTomorrow", test_isDateInTomorrow), |
| ("test_isDateInWeekend", test_isDateInWeekend), |
| ("test_rangeOfWeekendStartDate_interval_containingDate", test_rangeOfWeekendStartDate_interval_containingDate), |
| ("test_enumerateDatesStartingAfterDate_chineseEra_matchYearOne", test_enumerateDatesStartingAfterDate_chineseEra_matchYearOne), |
| ("test_enumerateDatesStartingAfterDate_ensureStrictlyIncreasingResults_minuteSecondClearing", test_enumerateDatesStartingAfterDate_ensureStrictlyIncreasingResults_minuteSecondClearing), |
| ] |
| } |
| } |