Skip to content

Added support for nextDate and enumerateDates to Calendar#93

Merged
marcprux merged 34 commits intoskiptools:mainfrom
fhasse95:Added-Calendar-Enumeration-Support
Mar 2, 2026
Merged

Added support for nextDate and enumerateDates to Calendar#93
marcprux merged 34 commits intoskiptools:mainfrom
fhasse95:Added-Calendar-Enumeration-Support

Conversation

@fhasse95
Copy link
Contributor

@fhasse95 fhasse95 commented Feb 14, 2026

This PR extends the Calendar class to include support for nextDate and enumerateDates.

The core logic was primarily adapted from the Swift Foundation repository to ensure parity with the native Swift behavior and minimize the risk of logic errors inherent in a full reimplementation. Since Skip currently only supports the Gregorian calendar, non-essential special cases were removed (e.g., lunar calendar offsets).

To ensure stability, I added several unit tests covering ranges, intervals, and enumeration. However, due to the complexity of calendar edge cases, it's possible that I overlooked a scenario.

Therefore, if you notice anaything, please let me know! 😊


Thank you for contributing to the Skip project! Please use this space to describe your change and add any labels (bug, enhancement, documentation, etc.) to help categorize your contribution.

Please review the contribution guide at https://skip.dev/docs/contributing/ for advice and guidance on making high-quality PRs.

Skip Pull Request Checklist:

  • REQUIRED: I have signed the Contributor Agreement
  • REQUIRED: I have tested my change locally with swift test
  • OPTIONAL: I have tested my change on an iOS simulator or device
  • OPTIONAL: I have tested my change on an Android emulator or device

  • AI was used to generate or assist with generating this PR. Please specify below how you used AI to help you, and what steps you have taken to manually verify the changes.

I used AI for assistance in creating additional unit tests for the calendar components and for consulting on Java-specific Calendar behaviors. Verification was done by manually reviewing all test cases, adjusting range expectations to match platform-specific constants, and ensuring the tests pass on both environments.


@cla-bot cla-bot bot added the cla-signed label Feb 14, 2026
var previouslyReturnedMatchDate: Date? = nil
var iterations = -1

repeat {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This STOP_EXHAUSTIVE_SEARCH_AFTER_MAX_ITERATIONS approach seems rather heavy-handed to me. I assume there's no equivalent function in Java's Calendar logic?

How does Foundation's Calendar do it?

Copy link
Contributor Author

@fhasse95 fhasse95 Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, Java's Calendar does not have a direct native equivalent to Apple's enumerateDates function which is why I decided to base the implementation on the logic found in the Swift Foundation library.

I agree that this approach seems heavy-handed for preventing infinite loops. However, the Swift Foundation implements it in exactly the same way (see: https://github.com/swiftlang/swift-foundation/blob/main/Sources/FoundationEssentials/Calendar/Calendar_Enumerate.swift#L472C9-L472C62).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick update, I haven't forgotten about this, but I'm still struggling with the size and complexity of the code this PR adds. I've been wondering if there might be some alternative, like internally using java.time.chrono if it offers some similar feature (disclosure: I have no idea if it does).

If there is really no other alternative solution, and if it isn't possible to get the size of the PR down, then I think we can go ahead and merge it since the test coverage is pretty good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @marcprux,
thanks for your feedback. I completely understand your concerns about the size and complexity of this PR.

I’ve carefully reviewed the available Java classes, but unfortunately, I couldn’t find any native equivalent to Calendar.nextDate or Calendar.enumerateDates in Java that fully replicates the specific behavior found in Swift. Theoretically, we could implement this ourselves using java.time.temporal.TemporalAdjuster, but this approach would still require significant custom logic to handle all edge cases, such as week-of-month transitions and varying search directions.

Therefore, to minimize the risk associated with a full reimplementation, I’ve decided to adapt the core logic directly from the official Swift Foundation repository. While a reimplementation might have resulted in fewer lines of code, it would significantly increase the likelihood of introducing behavioral differences between Android and iOS.

Since Skip's goal is to provide a reliable and equivalent experience to Swift Foundation, I believe that prioritizing behavioral parity over code conciseness is the most robust and maintainable approach. Therefore, I recommend moving forward with this implementation and merging the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think, @marcprux?

@fhasse95 fhasse95 marked this pull request as draft March 2, 2026 20:47
@fhasse95 fhasse95 marked this pull request as ready for review March 2, 2026 22:19
Copy link
Member

@marcprux marcprux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still have reservations about the sheer size of this PR, but since it doesn't seem like there's any other way to support the equivalent Foundation API, and since the changes are almost purely additive, I think we can go ahead and merge this once CI passes.

@fhasse95
Copy link
Contributor Author

fhasse95 commented Mar 2, 2026

Hi @marcprux,
thanks for the review and for understanding the necessity of these changes. I agree that the PR is quite large, but as you said, it is unfortunately necessary to ensure full parity with the Swift Foundation API.

The CI has now passed too. The previous failure was due to a minor issue with a non-deterministic date within one test used in the runner environment. I've now resolved this by using a fixed date instead.

That said, everything should be ready for merge now 😊

@marcprux marcprux merged commit 8e18673 into skiptools:main Mar 2, 2026
2 checks passed
@marcprux
Copy link
Member

marcprux commented Mar 2, 2026

Thanks for all the hard work! This fills in a significant gap in Skip Lite's Foundation support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants