-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add support for ISO8601 calendar and others #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -236,14 +236,23 @@ CFCalendarRef CFCalendarCopyCurrent(void) { | |||
} | |||
|
|||
Boolean _CFCalendarInitWithIdentifier(CFCalendarRef calendar, CFStringRef identifier) { | |||
if (identifier != kCFGregorianCalendar && identifier != kCFBuddhistCalendar && identifier != kCFJapaneseCalendar && identifier != kCFIslamicCalendar && identifier != kCFIslamicCivilCalendar && identifier != kCFHebrewCalendar && identifier != kCFChineseCalendar) { | |||
if (identifier != kCFGregorianCalendar && identifier != kCFBuddhistCalendar && identifier != kCFJapaneseCalendar && identifier != kCFIslamicCalendar && identifier != kCFIslamicCivilCalendar && identifier != kCFHebrewCalendar && identifier != kCFRepublicOfChinaCalendar && identifier != kCFPersianCalendar && identifier != kCFCalendarIdentifierCoptic && identifier != kCFCalendarIdentifierEthiopicAmeteMihret && identifier != kCFCalendarIdentifierEthiopicAmeteAlem && identifier != kCFChineseCalendar && identifier != kCFISO8601Calendar && identifier != kCFIslamicTabularCalendar && kCFIslamicUmmAlQuraCalendar) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know at what point is stops being an optimisation to look for calendars here. Perhaps it should just be a subset of the available calendars?
Also, there's a _CFCalendarInitWithIdentifier
and CFCalendarCreateWithIdentifier
-- I'm not sure of the difference between them (but I've only implemented this one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there's a typo at the end of the condition:
identifier != kCFIslamicTabularCalendar && kCFIslamicUmmAlQuraCalendar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, now that we are supporting all the calendar identifiers, do we need this if statement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if statement is about optimisation as much as anything else. The CFEqual
check performs the equality comparison as well but is more details if that fails, so by doing a first-pass through known good identifiers the fast path can be optimised. Whether it's worth doing that for every calendar or not is debatable.
else if (CFEqual(kCFRepublicOfChinaCalendar, identifier)) identifier = kCFRepublicOfChinaCalendar; | ||
else if (CFEqual(kCFPersianCalendar, identifier)) identifier = kCFPersianCalendar; | ||
else if (CFEqual(kCFIndianCalendar, identifier)) identifier = kCFIndianCalendar; | ||
else if (CFEqual(kCFCalendarIdentifierCoptic, identifier)) identifier = kCFCalendarIdentifierCoptic; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems there was a name change from kCFxxxCalendar to kCFCalendarXXxx, but I tried to add the older one here. However, I couldn't find the kCFCopticCalendar, so I didn't use that. I wonder if there's benefit in normalising all of these to kCFCalendarXxxx instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could define them here: https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Locale.subproj/CFLocaleKeys.c#L149
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to that idea, but will wait for the recommended solution before I make any further changes here.
@@ -126,7 +126,7 @@ CONST_STRING_DECL(kCFCalendarIdentifierChinese, "chinese"); | |||
CONST_STRING_DECL(kCFCalendarIdentifierRepublicOfChina, "roc"); | |||
CONST_STRING_DECL(kCFCalendarIdentifierPersian, "persian"); | |||
CONST_STRING_DECL(kCFCalendarIdentifierIndian, "indian"); | |||
CONST_STRING_DECL(kCFCalendarIdentifierISO8601, ""); | |||
CONST_STRING_DECL(kCFCalendarIdentifierISO8601, "iso8601"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this line change, the lookup for ISO8601 failed.
Calendar.Identifier.republicOfChina | ||
] { | ||
let calendar = Calendar(identifier: identifier) | ||
XCTAssertEqual(identifier,calendar.identifier) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if there's a generic property I should be looking up here for all calendars to test that they are created appropriately? At the moment it's just checking the identifier and initialiser.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have tests that create calendars for all types and then verify the year, month and day (something like gettingDatesOnGregorianCalendar
). That should be enough to make sure the underlying ICU is supporting all the types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not all calendars have the same concept of year, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment, the identifier is the most correct property to be checking for equality. The other properties of the calendar object don't necessarily indicate whether or not the calendar is of a certain kind (meaning "gregorian" "buddist" etc.). Since this test doesn't care about checking the equality of two calendar instances and only cares about the calendar instance having the correct identity, I think this is sufficient for now.
@alblue - Do the tests pass on Ubuntu 14.04 as well? We need to make sure the libicu there supports all these calendar types. Thanks. |
The list of valid keys did not include the ISO8601 calendar, which meant that code running on Linux that used it would fail. Fix this by adding the kCFISO8601Calendar and others into the list of known constants valid for calendars, and add tests for the Gregorian calendar, as well as for creating all other calendars. Issue: SR-2551
The tests build and pass on Linux, and (for example) you can identify certain components from the calendar, such as the identifier itself and the firstWeekday (which is 1 for all of them). It's not clear if that's the default though; for example, .amSymbol throws for both .gregorian and .iso8601. However, whether the ICU library supports the calendars or not I would expect the Swift code to be the same; that is, if the ICU library is upgraded to support new calendars we should expect to be able to sue them without having to change the Swift code for Calendar again. If we want to dynamically figure out which ones work then we should probably have a separate run-time initialisation step that builds up a list of known calendars from the ICU library. |
We really only should support the calendars identified by the constants exported in struct Calendar. It used to be the case that the identifier argument to init was a string, so you could pass whatever you liked. But in reality we only supported the known set anyway, which is why I changed it to an enum. |
@swift-ci please test |
I checked the set of identifiers at https://developer.apple.com/reference/foundation/nscalendar/1652687-calendar_identifiers against this set; I believe they are the same ones. |
The test in CI failed on the newly added calendars test:
I'll investigate further as to the cause, although I did not see this in the local Swift build that I tested it against. |
Rebuilt with latest HEAD and do not see the same failure as shown by the CI. This output from Linux:
I wonder if this is to do with the latest beta being installed onto the CI servers? |
Let me try again... |
@swift-ci please test |
Same problem. I can remove the failing test which was added here but it's not clear to me why the overrelease is happening, nor why I can't reproduce the error on my Linux build locally. |
OK, I'm able to reproduce this locally by running |
So the bug occurs when iterating across the fourth calendar item. Using this in the for loop:
prints out:
but then when running again, it goes through that calendar without any issues:
|
@alblue : Can we please keep this PR open while the apparent ARC issue is looked into? |
Sorry, didn't mean to close the request - hit the wrong button. I have raised https://bugs.swift.org/browse/SR-2879 to look into the release issues, and in the meantime, commented out some of the list contents so that we don't see the four calendars in a row issue that we were seeing earlier. This may allow the test to pass on the Swift CI in the meantime. |
Looks like I can't reopen this one for some reason. I'll create a new pull request. |
Since I can't re-open this, I've created #677 instead. I've rebased this on the calendar fix, so hopefully the test won't fail like it did last time. |
The list of valid keys did not include the ISO8601 calendar, which
meant that code running on Linux that used it would fail. Fix this
by adding the kCFISO8601Calendar and others into the list of known
constants valid for calendars, and add tests for the Gregorian
calendar, as well as for creating all other calendars.
Issue: SR-2551