Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.time.InstantSource;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.stream.Collectors;

Expand All @@ -37,7 +38,9 @@ public static MoonPhaseSet calculate(InstantSource instantSource, double julianD
final MoonPhaseSet result;

if (previousMP.needsRecalc(julianDate)) {
double julianDateMidnight = Math.floor(julianDate + 0.5) - 0.5;
ZoneOffset offset = zone instanceof ZoneOffset zo ? zo : zone.getRules().getOffset(instantSource.instant());
double offsetDays = offset.getTotalSeconds() / 86400.0;
double julianDateMidnight = Math.floor(julianDate + offsetDays + 0.5) - 0.5 - offsetDays;
Comment on lines +41 to +43

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair point.

double parentNewMoon = getPhase(julianDateMidnight, MoonPhase.NEW, false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

parentNewMoon still seems to be anchored to midnight here, which leaves another part of the #20104 regression in place.

Before #20104, midnight was used to find the remarkable phase dates for the local calendar day, while parentNewMoon was calculated separately from the current julianDate. That distinction seems important because lunar age is determined by the actual previous and next new moon instants, not by the start of the current calendar day.

The existing test provides a deterministic example: it has the Amsterdam new moon on 2019-03-06 at 17:04, which also agrees with published astronomical phase tables. If this calculation runs at 18:00 that day, julianDateMidnight is still 00:00. The backwards lookup therefore returns the February new moon while the forwards NEW lookup returns the already-past 17:04 new moon. getAgePercentDouble() consequently becomes greater than 1 instead of restarting close to zero after 17:04.

updateName() happens not to throw in this particular case because the entire local date is recognized as a NEW phase day, but the age percentage and degree are still outside their expected range.

Could the current lunation used for age be selected from julianDate again, while retaining the midnight-based lookup where it is needed to determine which remarkable phase belongs to the local calendar day? The requested regression tests could also cover immediately before and after a known new-moon timestamp.


Map<MoonPhase, Double> comingPhases = MoonPhase.remarkables().stream()
Expand Down
Loading