Skip to content

Symmetry454/Symmetry010: with(field, 0) must use the value, not ignore it - #451

Open
simpleqt wants to merge 1 commit into
ThreeTen:mainfrom
simpleqt:fix/symmetry-with-zero
Open

simpleqt wants to merge 1 commit into
ThreeTen:mainfrom
simpleqt:fix/symmetry-with-zero

Conversation

@simpleqt

@simpleqt simpleqt commented Nov 4, 2026 •

Copy link
Copy Markdown

Symmetry454Date.with(TemporalField, long) and Symmetry010Date.with started with

if (newValue == 0) {
    return this;
}

so a zero value silently left the date unchanged, and a value outside the field range was accepted too:

Symmetry454Date date = Symmetry454Date.of(2014, 5, 26);
date.with(EPOCH_DAY, 0);    // 2014/05/26, expected epoch day 0
date.with(YEAR, 0);         // 2014/05/26, expected year 0
date.with(DAY_OF_WEEK, 0);  // 2014/05/26, expected DateTimeException (range 1-7)

java.time treats zero as an ordinary value: LocalDate.of(2014, 5, 26).with(EPOCH_DAY, 0) is 1970-01-01 and with(DAY_OF_WEEK, 0) throws DateTimeException. Every other chronology in this package behaves the same way, because they inherit AbstractDate.with, which checks the field's range and uses the value - PaxDate, InternationalFixedDate, CopticDate, EthiopicDate, JulianDate, DiscordianDate, AccountingDate and BritishCutoverDate all override with without this special case.

The special case is removed, so with(EPOCH_DAY, 0) is epoch day 0, with(YEAR, 0) and with(PROLEPTIC_MONTH, 0) set the field to zero, and a value outside the field's range throws DateTimeException.

Verification:

  • TestSymmetry454Chronology and TestSymmetry010Chronology fail on main with these changes (14 failures: the three data rows per calendar that asserted the old no-op, the new invalid-value rows and the new test_with_TemporalField_zeroValue) and pass with the fix - 1493 tests;
  • the full suite passes: 13662 tests, 0 failures, 0 errors;
  • mvn checkstyle:check reports 0 violations.

Summary by CodeRabbit

  • Bug Fixes
    • Setting a date field to zero now applies that value instead of leaving the date unchanged.
    • Zero values outside a field’s valid range are rejected for both Symmetry010 and Symmetry454 dates.

…e it

Symmetry454Date.with(TemporalField, long) and Symmetry010Date.with returned
`this` when the new value was zero, so with(YEAR, 0), with(PROLEPTIC_MONTH, 0)
and with(EPOCH_DAY, 0) left the date unchanged, and values outside the field
range were accepted: with(DAY_OF_WEEK, 0) returned the date unchanged although
the day-of-week range is 1-7.

The two Symmetry calendars are the only ones in the package with this special
case; every other chronology inherits AbstractDate.with, which validates the
value and uses it, as does java.time (LocalDate.with(EPOCH_DAY, 0) is
1970-01-01 and LocalDate.with(DAY_OF_WEEK, 0) throws).

with(EPOCH_DAY, 0) is now epoch day 0, with(YEAR, 0) is year 0 and
with(DAY_OF_WEEK, 0) throws DateTimeException. The three data rows that
asserted the old no-op move to the invalid-value data, and rows are added for
the zero values of YEAR, PROLEPTIC_MONTH and EPOCH_DAY.
Copilot AI balanced review requested due to automatic review settings November 4, 2026 19:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Both Symmetry date classes now process zero-valued field updates through normal validation and field handling. Tests cover zero-valued year, proleptic month, and epoch day results, and reject zero for selected week and day fields.

Changes: Symmetry date zero-value updates

Layer / File(s) Summary
Field handling
src/main/java/org/threeten/extra/chrono/Symmetry010Date.java, src/main/java/org/threeten/extra/chrono/Symmetry454Date.java
Both date classes no longer return the current date when the requested field value is zero. The value proceeds through range validation and field handling or superclass delegation.
Zero-value tests
src/test/java/org/threeten/extra/chrono/TestSymmetry010Chronology.java, src/test/java/org/threeten/extra/chrono/TestSymmetry454Chronology.java
Tests check the results of setting YEAR, PROLEPTIC_MONTH, and EPOCH_DAY to zero. They also treat zero as invalid for ALIGNED_WEEK_OF_MONTH, ALIGNED_WEEK_OF_YEAR, and DAY_OF_WEEK.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested labels: Bug

Suggested reviewers: catull

Merge Risk: Minimal · up to f66db

No actionable merge-blocking issue was established for this change. The existing year-of-era contract inconsistency can be addressed separately.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the two classes changed (Symmetry454Date and Symmetry010Date) and the core behavior change: with(field, 0) now applies the zero value instead of ignoring it. The raw summary and object…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the two classes changed (Symmetry454Date and Symmetry010Date) and the core behavior change: with(field, 0) now applies the zero value instead of ignoring it. The raw summary and objectives both describe removing the zero-value early return from with(TemporalField, long) in both classes, so the title matches the main change.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 2 files.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3dd4a4bf-8691-418c-ac3d-9675c4013e88
Commits

Reviewing files that changed from the base of the PR and between b47344d and f66db69.

Files selected for processing: 4
  • src/main/java/org/threeten/extra/chrono/Symmetry010Date.java
  • src/main/java/org/threeten/extra/chrono/Symmetry454Date.java
  • src/test/java/org/threeten/extra/chrono/TestSymmetry010Chronology.java
  • src/test/java/org/threeten/extra/chrono/TestSymmetry454Chronology.java
Files with no reviewable changes: 2
  • src/main/java/org/threeten/extra/chrono/Symmetry010Date.java
  • src/main/java/org/threeten/extra/chrono/Symmetry454Date.java

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants