Skip to content
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

SunPosition.at and SolarTime.Calculator.sunset methods fail to make a round trip #991

Open
forrestguice opened this issue Nov 26, 2024 · 1 comment

Comments

@forrestguice
Copy link

forrestguice commented Nov 26, 2024

Description:
The sun's position at a given date/time (reported by SunPosition.at), and the date/time of that same position (reported by SolarTime.Calculator.sunset/sunrise) differ by several minutes.

Expected behavior
These methods should complete a "round trip" when used together.

Testing:

public class SunPositionTest1
{
    @Test
    public void test_SunPosition()
    {
        // setup
        double latitude = 33.45579;
        double longitude = -111.9485;  // Phoenix, AZ
        int altitude = 360;

        TimeZone tz = TimeZone.getTimeZone("UTC");
        Calendar date0 = Calendar.getInstance(tz);
        date0.setTimeInMillis(1639791526);   // Dec 17, 2021
        PlainDate plainDate = calendarToPlainDate(date0, tz);

        SolarTime solarTime = SolarTime.ofLocation(latitude, longitude, altitude, StdSolarCalculator.TIME4J);
        SolarTime.Calculator calculator = solarTime.getCalculator();

        // find elevation at given date/time
        Moment moment0 = TemporalType.JAVA_UTIL_DATE.translate(date0.getTime());
        net.time4j.calendar.astro.SunPosition position0 = net.time4j.calendar.astro.SunPosition.at(moment0, solarTime);
        double elevation0 = position0.getElevation();

        // find date/time of given elevation
        double geodeticAngle = StdSolarCalculator.TIME4J.getGeodeticAngle(latitude, altitude);
        double zenith = 90 + geodeticAngle - elevation0;
        Moment moment1 = calculator.sunset(plainDate, latitude, longitude, zenith);
        Calendar date1 = momentToCalendar(moment1, tz);

        double toleranceMs = 1 * 60 * 1000;    // 1min
        long difference = date1.getTimeInMillis() - date0.getTimeInMillis();
        assertTrue("expected time near " + date0.getTimeInMillis() + " (within " + (toleranceMs / (1000d * 60d)) + " min); " + date1.getTimeInMillis() + " differs by " + (difference / (1000d * 60d)) + " min",
                Math.abs(difference) < toleranceMs);
    }

    public static Calendar momentToCalendar(Moment moment, TimeZone timezone)
    {
        Calendar retValue = null;
        if (moment != null)
        {
            retValue = new GregorianCalendar();
            retValue.setTimeZone(timezone);
            retValue.setTime(TemporalType.JAVA_UTIL_DATE.from(moment));
        }
        return retValue;
    }

    public static PlainDate calendarToPlainDate(Calendar input, TimeZone timezone)
    {
        Moment moment = TemporalType.JAVA_UTIL_DATE.translate(input.getTime());
        ZonalOffset zonalOffset = ZonalOffset.ofTotalSeconds(timezone.getOffset(input.getTimeInMillis()) / 1000);
        return moment.toZonalTimestamp(zonalOffset).toDate();
    }
}

This test produces:

java.lang.AssertionError: expected time near 1639791526 (within 1.0 min); 1639978000 differs by 3.1079 min

In addition to the above, I wrote some additional tests that explore this another way. For example, test_sunPositionAtCivilRise results in:

java.lang.AssertionError: elevation should be near -6.0 (within 0.01); -6.597174049855876

Additional context
I noticed this bug several years ago while debugging Suntimes. I really should have filed this report back then, but somehow it slipped by. I also remember thinking "its close enough". 🤷‍♂️ Recently though a user opened this bug report, forrestguice/SuntimesWidget#844, which describes the symptoms that can be observed from Suntimes.

Version Info
implementation group: 'net.time4j', name: 'time4j-android', version: '4.8-2021a'

@forrestguice
Copy link
Author

forrestguice commented Nov 26, 2024

Actually, that linked issue doesn't show the problem I thought it did - apologies for adding noise.

It is something that becomes evident when using that UI though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant