@@ -454,6 +454,7 @@ extension Calendar {
454
454
}
455
455
456
456
internal func _enumerateDates( startingAfter start: Date ,
457
+ previouslyReturnedMatchDate: Date ? = nil ,
457
458
matching matchingComponents: DateComponents ,
458
459
matchingPolicy: MatchingPolicy ,
459
460
repeatedTimePolicy: RepeatedTimePolicy ,
@@ -470,7 +471,7 @@ extension Calendar {
470
471
let STOP_EXHAUSTIVE_SEARCH_AFTER_MAX_ITERATIONS = 100
471
472
472
473
var searchingDate = start
473
- var previouslyReturnedMatchDate : Date ? = nil
474
+ var previouslyReturnedMatchDate = previouslyReturnedMatchDate
474
475
var iterations = - 1
475
476
476
477
repeat {
@@ -511,14 +512,8 @@ extension Calendar {
511
512
matchingPolicy: MatchingPolicy ,
512
513
repeatedTimePolicy: RepeatedTimePolicy ,
513
514
direction: SearchDirection ,
514
- inSearchingDate: Date ,
515
+ inSearchingDate searchingDate : Date ,
515
516
previouslyReturnedMatchDate: Date ? ) throws -> SearchStepResult {
516
- var exactMatch = true
517
- var isLeapDay = false
518
- var searchingDate = inSearchingDate
519
-
520
- // NOTE: Several comments reference "isForwardDST" as a way to relate areas in forward DST handling.
521
- var isForwardDST = false
522
517
523
518
// Step A: Call helper method that does the searching
524
519
@@ -539,8 +534,25 @@ extension Calendar {
539
534
// TODO: Check if returning the same searchingDate has any purpose
540
535
return SearchStepResult ( result: nil , newSearchDate: searchingDate)
541
536
}
537
+
538
+ return try _adjustedDate ( unadjustedMatchDate, startingAfter: start, matching: matchingComponents, adjustedMatchingComponents: compsToMatch , matchingPolicy: matchingPolicy, repeatedTimePolicy: repeatedTimePolicy, direction: direction, inSearchingDate: searchingDate, previouslyReturnedMatchDate: previouslyReturnedMatchDate)
539
+ }
540
+
541
+ internal func _adjustedDate( _ unadjustedMatchDate: Date , startingAfter start: Date ,
542
+ allowStartDate: Bool = false ,
543
+ matching matchingComponents: DateComponents ,
544
+ adjustedMatchingComponents compsToMatch: DateComponents ,
545
+ matchingPolicy: MatchingPolicy ,
546
+ repeatedTimePolicy: RepeatedTimePolicy ,
547
+ direction: SearchDirection ,
548
+ inSearchingDate: Date ,
549
+ previouslyReturnedMatchDate: Date ? ) throws -> SearchStepResult {
550
+ var exactMatch = true
551
+ var isLeapDay = false
552
+ var searchingDate = inSearchingDate
542
553
543
- // Step B: Couldn't find matching date with a quick and dirty search in the current era, year, etc. Now try in the near future/past and make adjustments for leap situations and non-existent dates
554
+ // NOTE: Several comments reference "isForwardDST" as a way to relate areas in forward DST handling.
555
+ var isForwardDST = false
544
556
545
557
// matchDate may be nil, which indicates a need to keep iterating
546
558
// Step C: Validate what we found and then run block. Then prepare the search date for the next round of the loop
@@ -624,7 +636,7 @@ extension Calendar {
624
636
}
625
637
626
638
// If we get a result that is exactly the same as the start date, skip.
627
- if order == . orderedSame {
639
+ if !allowStartDate , order == . orderedSame {
628
640
return SearchStepResult ( result: nil , newSearchDate: searchingDate)
629
641
}
630
642
@@ -1393,7 +1405,7 @@ extension Calendar {
1393
1405
}
1394
1406
}
1395
1407
1396
- private func dateAfterMatchingEra( startingAt startDate: Date , components: DateComponents , direction: SearchDirection , matchedEra: inout Bool ) -> Date ? {
1408
+ internal func dateAfterMatchingEra( startingAt startDate: Date , components: DateComponents , direction: SearchDirection , matchedEra: inout Bool ) -> Date ? {
1397
1409
guard let era = components. era else {
1398
1410
// Nothing to do
1399
1411
return nil
@@ -1431,7 +1443,7 @@ extension Calendar {
1431
1443
}
1432
1444
}
1433
1445
1434
- private func dateAfterMatchingYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1446
+ internal func dateAfterMatchingYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1435
1447
guard let year = components. year else {
1436
1448
// Nothing to do
1437
1449
return nil
@@ -1466,7 +1478,7 @@ extension Calendar {
1466
1478
}
1467
1479
}
1468
1480
1469
- private func dateAfterMatchingYearForWeekOfYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1481
+ internal func dateAfterMatchingYearForWeekOfYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1470
1482
guard let yearForWeekOfYear = components. yearForWeekOfYear else {
1471
1483
// Nothing to do
1472
1484
return nil
@@ -1494,7 +1506,7 @@ extension Calendar {
1494
1506
}
1495
1507
}
1496
1508
1497
- private func dateAfterMatchingQuarter( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1509
+ internal func dateAfterMatchingQuarter( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1498
1510
guard let quarter = components. quarter else { return nil }
1499
1511
1500
1512
// Get the beginning of the year we need
@@ -1530,7 +1542,7 @@ extension Calendar {
1530
1542
}
1531
1543
}
1532
1544
1533
- private func dateAfterMatchingWeekOfYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1545
+ internal func dateAfterMatchingWeekOfYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1534
1546
guard let weekOfYear = components. weekOfYear else {
1535
1547
// Nothing to do
1536
1548
return nil
@@ -1569,7 +1581,7 @@ extension Calendar {
1569
1581
}
1570
1582
1571
1583
@available ( FoundationPreview 0 . 4 , * )
1572
- private func dateAfterMatchingDayOfYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1584
+ internal func dateAfterMatchingDayOfYear( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1573
1585
guard let dayOfYear = components. dayOfYear else {
1574
1586
// Nothing to do
1575
1587
return nil
@@ -1606,7 +1618,7 @@ extension Calendar {
1606
1618
return result
1607
1619
}
1608
1620
1609
- private func dateAfterMatchingMonth( startingAt startDate: Date , components: DateComponents , direction: SearchDirection , strictMatching: Bool ) throws -> Date ? {
1621
+ internal func dateAfterMatchingMonth( startingAt startDate: Date , components: DateComponents , direction: SearchDirection , strictMatching: Bool ) throws -> Date ? {
1610
1622
guard let month = components. month else {
1611
1623
// Nothing to do
1612
1624
return nil
@@ -1695,7 +1707,7 @@ extension Calendar {
1695
1707
return result
1696
1708
}
1697
1709
1698
- private func dateAfterMatchingWeekOfMonth( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1710
+ internal func dateAfterMatchingWeekOfMonth( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1699
1711
guard let weekOfMonth = components. weekOfMonth else {
1700
1712
// Nothing to do
1701
1713
return nil
@@ -1784,7 +1796,7 @@ extension Calendar {
1784
1796
return result
1785
1797
}
1786
1798
1787
- private func dateAfterMatchingWeekdayOrdinal( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1799
+ internal func dateAfterMatchingWeekdayOrdinal( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1788
1800
guard let weekdayOrdinal = components. weekdayOrdinal else {
1789
1801
// Nothing to do
1790
1802
return nil
@@ -1887,7 +1899,7 @@ extension Calendar {
1887
1899
return result
1888
1900
}
1889
1901
1890
- private func dateAfterMatchingWeekday( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1902
+ internal func dateAfterMatchingWeekday( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
1891
1903
guard let weekday = components. weekday else {
1892
1904
// Nothing to do
1893
1905
return nil
@@ -1944,7 +1956,7 @@ extension Calendar {
1944
1956
return result
1945
1957
}
1946
1958
1947
- private func dateAfterMatchingDay( startingAt startDate: Date , originalStartDate: Date , components comps: DateComponents , direction: SearchDirection ) throws -> Date ? {
1959
+ internal func dateAfterMatchingDay( startingAt startDate: Date , originalStartDate: Date , components comps: DateComponents , direction: SearchDirection ) throws -> Date ? {
1948
1960
guard let day = comps. day else {
1949
1961
// Nothing to do
1950
1962
return nil
@@ -2045,7 +2057,7 @@ extension Calendar {
2045
2057
return result
2046
2058
}
2047
2059
2048
- private func dateAfterMatchingHour( startingAt startDate: Date , originalStartDate: Date , components: DateComponents , direction: SearchDirection , findLastMatch: Bool , isStrictMatching: Bool , matchingPolicy: MatchingPolicy ) throws -> Date ? {
2060
+ internal func dateAfterMatchingHour( startingAt startDate: Date , originalStartDate: Date , components: DateComponents , direction: SearchDirection , findLastMatch: Bool , isStrictMatching: Bool , matchingPolicy: MatchingPolicy ) throws -> Date ? {
2049
2061
guard let hour = components. hour else {
2050
2062
// Nothing to do
2051
2063
return nil
@@ -2182,7 +2194,7 @@ extension Calendar {
2182
2194
return result
2183
2195
}
2184
2196
2185
- private func dateAfterMatchingMinute( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
2197
+ internal func dateAfterMatchingMinute( startingAt: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
2186
2198
guard let minute = components. minute else {
2187
2199
// Nothing to do
2188
2200
return nil
@@ -2211,7 +2223,7 @@ extension Calendar {
2211
2223
return result
2212
2224
}
2213
2225
2214
- private func dateAfterMatchingSecond( startingAt startDate: Date , originalStartDate: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
2226
+ internal func dateAfterMatchingSecond( startingAt startDate: Date , originalStartDate: Date , components: DateComponents , direction: SearchDirection ) throws -> Date ? {
2215
2227
guard let second = components. second else {
2216
2228
// Nothing to do
2217
2229
return nil
@@ -2277,7 +2289,7 @@ extension Calendar {
2277
2289
return result
2278
2290
}
2279
2291
2280
- private func dateAfterMatchingNanosecond( startingAt: Date , components: DateComponents , direction: SearchDirection ) -> Date ? {
2292
+ internal func dateAfterMatchingNanosecond( startingAt: Date , components: DateComponents , direction: SearchDirection ) -> Date ? {
2281
2293
guard let nanosecond = components. nanosecond else {
2282
2294
// Nothing to do
2283
2295
return nil
0 commit comments