Skip to content

Commit c9dc1be

Browse files
committed
add more
1 parent 8168094 commit c9dc1be

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

src/main/java/com/kosherjava/zmanim/AstronomicalCalendar.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ protected Date getDateFromTime(double time, SolarEvent solarEvent) {
654654
cal.add(Calendar.DAY_OF_MONTH, 1);
655655
} else if (solarEvent == SolarEvent.NOON && localTimeHours + hours < 0) {
656656
cal.add(Calendar.DAY_OF_MONTH, 1);
657+
} else if (solarEvent == SolarEvent.NOON && localTimeHours + hours > 24) {
658+
cal.add(Calendar.DAY_OF_MONTH, -1);
657659
}
658660

659661
cal.set(Calendar.HOUR_OF_DAY, hours);

src/test/java/com/kosherjava/zmanim/AstronomicalCalendarTest.java

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,110 @@ public void testAntiMeridianNoonCalculation() {
7777
(resultCalendar.get(Calendar.MONTH) + 1) + "-" +
7878
resultCalendar.get(Calendar.DAY_OF_MONTH));
7979
}
80+
81+
/**
82+
* Regression test for eastern anti-meridian noon calculation bug.
83+
*
84+
* This test verifies the opposite case from testAntiMeridianNoonCalculation,
85+
* where the location is on the EASTERN side of the anti-meridian (positive
86+
* longitude near +180°).
87+
*
88+
* The original bug had two parts:
89+
* 1. The condition "localTimeHours + hours > 24" was correct but used -1
90+
* (subtract day) which was wrong
91+
* 2. Only handled one side of anti-meridian, not both
92+
*
93+
* The fix uses: (localTimeHours + hours < 0 || localTimeHours + hours > 24)
94+
* and adds +1 day for BOTH cases.
95+
*
96+
* Test case from random testing that originally failed:
97+
* - Date: 1933-11-21
98+
* - Location: (45.272612853681636, 178.99188812570947), Elevation:
99+
* 77.9172657062239
100+
* - Timezone: Pacific/Auckland (approximately GMT+12)
101+
*
102+
* Before fix: Noon was calculated for 1933-11-22 (wrong day, +1 day error)
103+
* After fix: Noon should be calculated for 1933-11-21 (correct day)
104+
*/
105+
@Test
106+
public void testEasternAntiMeridianNoonCalculation() {
107+
// Create location near eastern anti-meridian
108+
double latitude = 45.272612853681636;
109+
double longitude = 178.99188812570947;
110+
double elevation = 77.9172657062239;
111+
TimeZone timeZone = TimeZone.getTimeZone("Pacific/Auckland"); // GMT+12/+13
112+
113+
GeoLocation location = new GeoLocation("Test Location", latitude, longitude, elevation, timeZone);
114+
AstronomicalCalendar calendar = new AstronomicalCalendar(location);
115+
116+
// Set the test date: November 21, 1933
117+
calendar.getCalendar().set(Calendar.YEAR, 1933);
118+
calendar.getCalendar().set(Calendar.MONTH, Calendar.NOVEMBER);
119+
calendar.getCalendar().set(Calendar.DAY_OF_MONTH, 21);
120+
calendar.getCalendar().set(Calendar.HOUR_OF_DAY, 11);
121+
calendar.getCalendar().set(Calendar.MINUTE, 47);
122+
calendar.getCalendar().set(Calendar.SECOND, 40);
123+
124+
// Get solar noon (sun transit)
125+
Date sunTransit = calendar.getSunTransit();
126+
127+
Assert.assertNotNull("Sun transit should not be null", sunTransit);
128+
129+
// Create a calendar to check the date
130+
Calendar resultCalendar = Calendar.getInstance(timeZone);
131+
resultCalendar.setTime(sunTransit);
132+
133+
// The calculated noon should be on November 21, not November 22
134+
Assert.assertEquals("Solar noon year should match input year",
135+
1933, resultCalendar.get(Calendar.YEAR));
136+
Assert.assertEquals("Solar noon month should match input month",
137+
Calendar.NOVEMBER, resultCalendar.get(Calendar.MONTH));
138+
Assert.assertEquals("Solar noon day should match input day (was off by +1 day before fix)",
139+
21, resultCalendar.get(Calendar.DAY_OF_MONTH));
140+
141+
System.out.println("Input date: 1933-11-21");
142+
System.out.println("Calculated sun transit: " + sunTransit);
143+
System.out.println("Transit date components: " +
144+
resultCalendar.get(Calendar.YEAR) + "-" +
145+
(resultCalendar.get(Calendar.MONTH) + 1) + "-" +
146+
resultCalendar.get(Calendar.DAY_OF_MONTH));
147+
}
148+
149+
/**
150+
* Additional test for anti-meridian with various longitudes.
151+
* Tests that noon always falls on the correct date regardless of longitude.
152+
*/
153+
@Test
154+
public void testNoonDateConsistency() {
155+
// Test various longitudes near both sides of the anti-meridian
156+
double[] testLongitudes = {
157+
-179.5, // Just west of anti-meridian
158+
-179.0,
159+
178.0, // Just east of anti-meridian
160+
178.5,
161+
179.0,
162+
179.5
163+
};
164+
165+
for (double longitude : testLongitudes) {
166+
TimeZone tz = TimeZone.getTimeZone("Etc/GMT+12");
167+
GeoLocation location = new GeoLocation("Test", 0.0, longitude, 0.0, tz);
168+
AstronomicalCalendar calendar = new AstronomicalCalendar(location);
169+
170+
// Set a specific date
171+
calendar.getCalendar().set(2024, Calendar.JUNE, 15, 12, 0, 0);
172+
int inputDay = calendar.getCalendar().get(Calendar.DAY_OF_MONTH);
173+
174+
Date sunTransit = calendar.getSunTransit();
175+
Assert.assertNotNull("Sun transit should not be null for longitude " + longitude, sunTransit);
176+
177+
Calendar result = Calendar.getInstance(tz);
178+
result.setTime(sunTransit);
179+
int resultDay = result.get(Calendar.DAY_OF_MONTH);
180+
181+
Assert.assertEquals(
182+
"Solar noon day should match input day for longitude " + longitude,
183+
inputDay, resultDay);
184+
}
185+
}
80186
}

0 commit comments

Comments
 (0)