You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Proposals/0017-expanded-calendar-support.md
+19-12Lines changed: 19 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,7 +27,7 @@ Foundation will add constants to support the new calendar types.
27
27
28
28
Some calendars added by this proposal have a unique feature of "leap days", where two consecutive days can have the same numeric value. This new feature will have impact on APIs that search/match dates.
29
29
30
-
This property will be called isAdhikaDay, to indicate it is used in Hindu calendars which are the only calendars that has this feature. More details about the naming is provided in the section `Alternatives considered` at the end of the document.
30
+
This property will be called `isRepeatedDay`. More details about the naming is provided in the section `Alternatives considered` at the end of the document.
31
31
32
32
## Detailed design
33
33
@@ -86,7 +86,7 @@ Foundation will add new string constants for new calendar identifiers for NSCale
86
86
}
87
87
```
88
88
89
-
Following are the code changes required to support new calendar property isAdhikaDay
89
+
Following are the code changes required to support new calendar property isRepeatedDay
90
90
91
91
92
92
**Calendar.swift**
@@ -96,11 +96,20 @@ Following are the code changes required to support new calendar property isAdhik
96
96
publicenumComponent : Sendable {
97
97
// ...
98
98
@available(FoundationPreview 6.2, *)
99
-
caseisAdhikaDay
99
+
caseisRepeatedDay
100
100
// ....
101
101
}
102
102
```
103
103
104
+
**DateComponents.swift**
105
+
106
+
```swift
107
+
extensionDateComponents {
108
+
@available(FoundationPreview 6.2, *)
109
+
publicvar isRepeatedDay: Bool? { getset }
110
+
}
111
+
```
112
+
104
113
## Impact on existing code
105
114
106
115
Vietnamese and Korean calendars have no special considerations.
@@ -113,19 +122,17 @@ Calendars used in India are introducing the new field for the leap day. Clients
113
122
var components =DateComponents()
114
123
```
115
124
116
-
**Second**, the comparison for calendar dates will account for this field. Two dates differs if they don't have the same value for isAdhikaDay
125
+
**Second**, the comparison for calendar dates will account for this field. Two dates differs if they don't have the same value for isRepeatedDay
117
126
118
127
For example, the clients may currently use following check
119
128
120
129
```swift
121
130
cal.compare(d1, d2)
122
131
```
123
132
124
-
For Hindu calendars, this would only compare equal if they're both Adhika day or if they are both not. For non-Hindu calendars, isAdhikaDay property will be ignored.
125
-
126
-
**Third**, the calendar date arithmetic will be updated to correctly calculate the dates regarding `adhikaDay`. When working with Hindu calendars, as the leap days can occur at any position, looking for next day would have to involve recalculation.
133
+
For Hindu calendars, this would only compare equal if their year, month, day, and repeated day values are all the same. For non-Hindu calendars, isRepeatedDay property will be ignored.
127
134
128
-
As a general rule, behavior of `isAdhikaDay` will replicate `isLeapMonth` in APIs doing matching and searching.
135
+
As a general rule, behavior of `isRepeatedDay` will replicate `isLeapMonth` in APIs doing matching and searching.
129
136
130
137
For example, let's explain what is the expected behavior in this API that enumerate the next date
131
138
@@ -144,17 +151,17 @@ Clients using this function to enumerate the next date after `date`, matching th
144
151
145
152
* If start is on a leap day
146
153
147
-
*`strict`: If components.isAdhikaDay is true, this gives you the next date that is also a leap day that shares the same day, month, year number (i.e. all those specified with the comps argument) as start. If only a subset of `DateComponents` is specified, for example only the month, this gives you the next date which is a leap day with same month. If no arguments are given for `DateComponents`, this gives the next date that is also a leap day. If components.isAdhikaDay is false, this function gives you the next date that matches the day/month/year number but one that is not a leap day.
154
+
*`strict`: If components.isRepeatedDay is true, this gives you the next date that is also a leap day that shares the same day, month, year number (i.e. all those specified with the comps argument) as start. If only a subset of `DateComponents` is specified, for example only the month, this gives you the next date which is a leap day with same month. If no arguments are given for `DateComponents`, this gives the next date that is also a leap day. If components.isRepeatedDay is false, this function gives you the next date that matches the day/month/year number but one that is not a leap day.
148
155
149
156
* If start is not on a leap day
150
157
151
-
*`strict`: If components.isAdhikaDay is true, this gives you the next date that is a leap day that shares the same day, month, year number (i.e. all those specified with the comps argument) as start but a leap day. If components.isAdhikaDay is false, this function gives you the next date that matches the day/month/year number that is not a leap day.
158
+
*`strict`: If components.isRepeatedDay is true, this gives you the next date that is a leap day that shares the same day, month, year number (i.e. all those specified with the comps argument) as start but a leap day. If components.isRepeatedDay is false, this function gives you the next date that matches the day/month/year number that is not a leap day.
152
159
153
160
For the `direction` and `repeatedTimePolicy`:
154
161
155
162
*`backward`: This flag does not affect how leap day search is handled, but merely changes the search direction so that it finds the match before start rather than after start.
156
163
157
-
*`first`: If there are two or more matching dates, and all their components are the same, including isAdhikaDay, the function returns the first date.
164
+
*`first`: If there are two or more matching dates, and all their components are the same, including isRepeatedDay, the function returns the first date.
158
165
159
166
*`last`: Similar to `first`, but the function returns the last match.
160
167
@@ -178,6 +185,6 @@ public func dates(byAdding components: DateComponents,
178
185
179
186
As mentioned before, the leap day is a unique feature of some of new calendars. It appears when a certain astronomical position of Sun and Moon happens which means it can appear on any date. That differs from Gregorian leap day of February 29th, which happens every four years (approximately) and it is always on the same day.
180
187
181
-
This property will be called isAdhikaDay to clearly indicate it is related to Hindu lunisolar calendars. The alternative was to call it isLeapDay, but that may lead to confusion with Gregorian calendar
188
+
This property will be called isRepeatedDay to clearly indicate it is a day that repeats. The alternatives were to call it isLeapDay which might lead to confusion with Gregorian calendar, or isAdhikaDay which would be unclear for developers unfamiliar with Hindu calendar terminology.
182
189
183
190
Another point of discussion was whether to use Bengali vs Bangla and Oriya vs Odia. There has been an effort to stop using the older colloquial names Bengali and Oriya and to switch to the now-accepted names Bangla and Odia. While most of the attention has gone to the language names, the same naming should also be used for the calendar names, despite them receiving less attention.
@available(macOS, deprecated:10000, introduced:12, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
214
-
@available(iOS, deprecated:10000, introduced:15, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
215
-
@available(tvOS, deprecated:10000, introduced:15, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
216
-
@available(watchOS, deprecated:10000, introduced:8, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
217
-
@available(visionOS, deprecated:10000, introduced:1, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
212
+
@available(macOS, deprecated:26, introduced:12, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
213
+
@available(iOS, deprecated:26, introduced:15, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
214
+
@available(tvOS, deprecated:26, introduced:15, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
215
+
@available(watchOS, deprecated:26, introduced:8, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
216
+
@available(visionOS, deprecated:26, introduced:1, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
218
217
@available(*, deprecated, message:"AttributedString.Runs.Index should not be used as a Strideable and should instead be offset using the API provided by AttributedString.Runs")
219
218
extensionAttributedString.Runs.Index:Strideable{
220
219
publicfunc distance(to other:Self)->Int{
221
220
// This isn't perfect (since two non-sliced indices might have other sliced runs between them) but checking is better than nothing
222
221
precondition(!self._withinDiscontiguous && !other._withinDiscontiguous,"AttributedString.Runs.Index's Strideable conformance may not be used with discontiguous sliced runs")
223
222
return other._runOffset -self._runOffset
224
223
}
225
-
224
+
226
225
publicfunc advanced(by n:Int)->Self{
227
226
precondition(!self._withinDiscontiguous,"AttributedString.Runs.Index's Strideable conformance may not be used with discontiguous sliced runs")
228
227
returnSelf(_runOffset:self._runOffset + n, withinDiscontiguous:false)
// The algorithms that call this function assume that isLeapMonth counts as a 'highest unit set', but the order is after nanosecond.
298
+
// The algorithms that call this function assume that isLeapMonth and isRepeatedDay can count as 'highest unit set', but they are ordered after nanosecond.
0 commit comments