17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 1996-2010, International Business Machines Corporation and    *
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.                                                *
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.calendar;
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// AstroTest
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale;
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.test.TestFmwk;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.CalendarAstronomer;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.CalendarAstronomer.Ecliptic;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.CalendarAstronomer.Equatorial;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.DateFormat;
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.Calendar;
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.GregorianCalendar;
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.SimpleTimeZone;
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone;
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// TODO: try finding next new moon after  07/28/1984 16:00 GMT
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class AstroTest extends TestFmwk {
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static void main(String[] args) throws Exception {
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new AstroTest().run(args);
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static final double PI = Math.PI;
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestSolarLongitude() {
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0, "UTC"));
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer astro = new CalendarAstronomer();
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // year, month, day, hour, minute, longitude (radians), ascension(radians), declination(radians)
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final double tests[][] = {
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            { 1980, 7, 27, 00, 00, 2.166442986535465, 2.2070499713207730, 0.3355704075759270 },
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            { 1988, 7, 27, 00, 00, 2.167484927693959, 2.2081183335606176, 0.3353093444275315 },
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("");
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < tests.length; i++) {
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            gc.clear();
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            gc.set((int)tests[i][0], (int)tests[i][1]-1, (int)tests[i][2], (int)tests[i][3], (int) tests[i][4]);
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            astro.setDate(gc.getTime());
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            double longitude = astro.getSunLongitude();
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (longitude != tests[i][5]) {
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((float)longitude == (float)tests[i][5]) {
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("longitude(" + longitude +
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][5](" + tests[i][5] +
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") in double for test " + i);
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: longitude(" + longitude +
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][5](" + tests[i][5] +
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") for test " + i);
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Equatorial result = astro.getSunPosition();
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (result.ascension != tests[i][6]) {
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((float)result.ascension == (float)tests[i][6]) {
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("result.ascension(" + result.ascension +
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][6](" + tests[i][6] +
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") in double for test " + i);
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: result.ascension(" + result.ascension +
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][6](" + tests[i][6] +
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") for test " + i);
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (result.declination != tests[i][7]) {
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((float)result.declination == (float)tests[i][7]) {
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("result.declination(" + result.declination +
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][7](" + tests[i][7] +
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") in double for test " + i);
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: result.declination(" + result.declination +
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][7](" + tests[i][7] +
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") for test " + i);
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestLunarPosition() {
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0, "UTC"));
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer astro = new CalendarAstronomer();
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // year, month, day, hour, minute, ascension(radians), declination(radians)
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final double tests[][] = {
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            { 1979, 2, 26, 16, 00, -0.3778379118188744, -0.1399698825594198 },
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("");
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < tests.length; i++) {
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            gc.clear();
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            gc.set((int)tests[i][0], (int)tests[i][1]-1, (int)tests[i][2], (int)tests[i][3], (int) tests[i][4]);
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            astro.setDate(gc.getTime());
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Equatorial result = astro.getMoonPosition();
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (result.ascension != tests[i][5]) {
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((float)result.ascension == (float)tests[i][5]) {
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("result.ascension(" + result.ascension +
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][5](" + tests[i][5] +
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") in double for test " + i);
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: result.ascension(" + result.ascension +
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][5](" + tests[i][5] +
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") for test " + i);
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (result.declination != tests[i][6]) {
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((float)result.declination == (float)tests[i][6]) {
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("result.declination(" + result.declination +
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][6](" + tests[i][6] +
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") in double for test " + i);
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: result.declination(" + result.declination +
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") !=  tests[i][6](" + tests[i][6] +
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") for test " + i);
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCoordinates() {
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer astro = new CalendarAstronomer();
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Equatorial result = astro.eclipticToEquatorial(139.686111 * PI/ 180.0, 4.875278* PI / 180.0);
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("result is " + result + ";  " + result.toHmsString());
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCoverage() {
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar cal = new GregorianCalendar(1958, Calendar.AUGUST, 15);
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date then = cal.getTime();
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer myastro = new CalendarAstronomer(then);
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //Latitude:  34 degrees 05' North
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //Longitude:  118 degrees 22' West
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double laLat = 34 + 5d/60, laLong = 360 - (118 + 22d/60);
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer myastro2 = new CalendarAstronomer(laLong, laLat);
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double eclLat = laLat * Math.PI / 360;
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double eclLong = laLong * Math.PI / 360;
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Ecliptic ecl = new Ecliptic(eclLat, eclLong);
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("ecliptic: " + ecl);
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer myastro3 = new CalendarAstronomer();
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        myastro3.setJulianDay((4713 + 2000) * 365.25);
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer[] astronomers = {
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            myastro, myastro2, myastro3, myastro2 // check cache
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < astronomers.length; ++i) {
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            CalendarAstronomer astro = astronomers[i];
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("astro: " + astro);
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   time: " + astro.getTime());
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   date: " + astro.getDate());
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   cent: " + astro.getJulianCentury());
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   gw sidereal: " + astro.getGreenwichSidereal());
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   loc sidereal: " + astro.getLocalSidereal());
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   equ ecl: " + astro.eclipticToEquatorial(ecl));
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   equ long: " + astro.eclipticToEquatorial(eclLong));
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   horiz: " + astro.eclipticToHorizon(eclLong));
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   sunrise: " + new Date(astro.getSunRiseSet(true)));
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   sunset: " + new Date(astro.getSunRiseSet(false)));
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   moon phase: " + astro.getMoonPhase());
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   moonrise: " + new Date(astro.getMoonRiseSet(true)));
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   moonset: " + new Date(astro.getMoonRiseSet(false)));
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   prev summer solstice: " + new Date(astro.getSunTime(CalendarAstronomer.SUMMER_SOLSTICE, false)));
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   next summer solstice: " + new Date(astro.getSunTime(CalendarAstronomer.SUMMER_SOLSTICE, true)));
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   prev full moon: " + new Date(astro.getMoonTime(CalendarAstronomer.FULL_MOON, false)));
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("   next full moon: " + new Date(astro.getMoonTime(CalendarAstronomer.FULL_MOON, true)));
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static final long DAY_MS = 24*60*60*1000L;
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestSunriseTimes() {
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //        logln("Sunrise/Sunset times for San Jose, California, USA");
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //        CalendarAstronomer astro = new CalendarAstronomer(-121.55, 37.20);
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // We'll use a table generated by the UNSO website as our reference
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // From: http://aa.usno.navy.mil/
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //-Location: W079 25, N43 40
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //-Rise and Set for the Sun for 2001
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //-Zone:  4h West of Greenwich
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] USNO = {
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,59, 19,45,
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,57, 19,46,
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,56, 19,47,
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,54, 19,48,
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,52, 19,49,
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,50, 19,51,
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,48, 19,52,
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,47, 19,53,
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,45, 19,54,
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,43, 19,55,
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,42, 19,57,
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,40, 19,58,
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,38, 19,59,
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,36, 20, 0,
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,35, 20, 1,
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,33, 20, 3,
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,31, 20, 4,
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,30, 20, 5,
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,28, 20, 6,
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,27, 20, 7,
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,25, 20, 8,
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,23, 20,10,
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,22, 20,11,
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,20, 20,12,
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,19, 20,13,
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,17, 20,14,
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,16, 20,16,
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,14, 20,17,
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,13, 20,18,
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             6,11, 20,19,
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Sunrise/Sunset times for Toronto, Canada");
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer astro = new CalendarAstronomer(-(79+25/60), 43+40/60);
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // As of ICU4J 2.8 the ICU4J time zones implement pass-through
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // to the underlying JDK.  Because of variation in the
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // underlying JDKs, we have to use a fixed-offset
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // SimpleTimeZone to get consistent behavior between JDKs.
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // The offset we want is [-18000000, 3600000] (raw, dst).
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [aliu 10/15/03]
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // TimeZone tz = TimeZone.getTimeZone("America/Montreal");
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone tz = new SimpleTimeZone(-18000000 + 3600000, "Montreal(FIXED)");
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar cal = new GregorianCalendar(tz, Locale.US);
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar cal2 = new GregorianCalendar(tz, Locale.US);
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.clear();
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.set(Calendar.YEAR, 2001);
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.set(Calendar.MONTH, Calendar.APRIL);
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.set(Calendar.DAY_OF_MONTH, 1);
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.set(Calendar.HOUR_OF_DAY, 12); // must be near local noon for getSunRiseSet to work
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormat df = DateFormat.getTimeInstance(cal, DateFormat.MEDIUM, Locale.US);
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormat df2 = DateFormat.getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US);
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormat day = DateFormat.getDateInstance(cal, DateFormat.MEDIUM, Locale.US);
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i < 30; i++) {
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            astro.setDate(cal.getTime());
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date sunrise = new Date(astro.getSunRiseSet(true));
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date sunset = new Date(astro.getSunRiseSet(false));
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.setTime(cal.getTime());
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.set(Calendar.SECOND,      0);
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.set(Calendar.MILLISECOND, 0);
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.set(Calendar.HOUR_OF_DAY, USNO[4*i+0]);
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.set(Calendar.MINUTE,      USNO[4*i+1]);
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date exprise = cal2.getTime();
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.set(Calendar.HOUR_OF_DAY, USNO[4*i+2]);
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal2.set(Calendar.MINUTE,      USNO[4*i+3]);
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date expset = cal2.getTime();
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Compute delta of what we got to the USNO data, in seconds
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int deltarise = Math.abs((int)(sunrise.getTime() - exprise.getTime()) / 1000);
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int deltaset = Math.abs((int)(sunset.getTime() - expset.getTime()) / 1000);
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Allow a deviation of 0..MAX_DEV seconds
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // It would be nice to get down to 60 seconds, but at this
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // point that appears to be impossible without a redo of the
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // algorithm using something more advanced than Duffett-Smith.
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            final int MAX_DEV = 180;
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (deltarise > MAX_DEV || deltaset > MAX_DEV) {
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (deltarise > MAX_DEV) {
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: " + day.format(cal.getTime()) +
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          ", Sunrise: " + df2.format(sunrise) +
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          " (USNO " + df.format(exprise) +
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          " d=" + deltarise + "s)");
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln(day.format(cal.getTime()) +
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          ", Sunrise: " + df.format(sunrise) +
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          " (USNO " + df.format(exprise) + ")");
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (deltaset > MAX_DEV) {
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: " + day.format(cal.getTime()) +
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          ", Sunset: " + df2.format(sunset) +
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          " (USNO " + df.format(expset) +
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          " d=" + deltaset + "s)");
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln(day.format(cal.getTime()) +
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          ", Sunset: " + df.format(sunset) +
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          " (USNO " + df.format(expset) + ")");
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln(day.format(cal.getTime()) +
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ", Sunrise: " + df.format(sunrise) +
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      " (USNO " + df.format(exprise) + ")" +
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ", Sunset: " + df.format(sunset) +
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      " (USNO " + df.format(expset) + ")");
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.add(Calendar.DATE, 1);
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        CalendarAstronomer a = new CalendarAstronomer(-(71+5/60), 42+37/60);
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.clear();
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.set(cal.YEAR, 1986);
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.set(cal.MONTH, cal.MARCH);
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.set(cal.DATE, 10);
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.set(cal.YEAR, 1988);
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.set(cal.MONTH, cal.JULY);
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.set(cal.DATE, 27);
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        a.setDate(cal.getTime());
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        long r = a.getSunRiseSet2(true);
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestBasics() {
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Check that our JD computation is the same as the book's (p. 88)
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer astro = new CalendarAstronomer();
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar cal3 = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US);
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormat d3 = DateFormat.getDateTimeInstance(cal3, DateFormat.MEDIUM,DateFormat.MEDIUM,Locale.US);
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal3.clear();
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal3.set(Calendar.YEAR, 1980);
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal3.set(Calendar.MONTH, Calendar.JULY);
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal3.set(Calendar.DATE, 27);
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        astro.setDate(cal3.getTime());
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double jd = astro.getJulianDay() - 2447891.5;
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double exp = -3444;
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (jd == exp) {
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln(d3.format(cal3.getTime()) + " => " + jd);
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: " + d3.format(cal3.getTime()) + " => " + jd +
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  ", expected " + exp);
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal3.clear();
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal3.set(cal3.YEAR, 1990);
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal3.set(cal3.MONTH, Calendar.JANUARY);
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal3.set(cal3.DATE, 1);
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal3.add(cal3.DATE, -1);
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        astro.setDate(cal3.getTime());
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        astro.foo();
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestMoonAge(){
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0,"GMT"));
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CalendarAstronomer calastro = new CalendarAstronomer();
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // more testcases are around the date 05/20/2012
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //ticket#3785  UDate ud0 = 1337557623000.0;
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double testcase[][] = {{2012, 5, 20 , 16 , 48, 59},
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2012, 5, 20 , 16 , 47, 34},
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2012, 5, 21, 00, 00, 00},
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2012, 5, 20, 14, 55, 59},
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2012, 5, 21, 7, 40, 40},
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2023, 9, 25, 10,00, 00},
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2008, 7, 7, 15, 00, 33},
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {1832, 9, 24, 2, 33, 41 },
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2016, 1, 31, 23, 59, 59},
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {2099, 5, 20, 14, 55, 59}
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Moon phase angle - Got from http://www.moonsystem.to/checkupe.htm
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double angle[] = {356.8493418421329, 356.8386760059673, 0.09625415252237701, 355.9986960782416, 3.5714026601303317, 124.26906744384183, 59.80247650195558, 357.54163205513123, 268.41779281511094, 4.82340276581624};
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double precision = PI/32;
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(int i=0; i<testcase.length; i++){
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            gc.clear();
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String testString = "CASE["+i+"]: Year "+(int)testcase[i][0]+" Month "+(int)testcase[i][1]+" Day "+
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    (int)testcase[i][2]+" Hour "+(int)testcase[i][3]+" Minutes "+(int)testcase[i][4]+
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    " Seconds "+(int)testcase[i][5];
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            gc.set((int)testcase[i][0],(int)testcase[i][1]-1,(int)testcase[i][2],(int)testcase[i][3],(int)testcase[i][4], (int)testcase[i][5]);
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            calastro.setDate(gc.getTime());
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            double expectedAge = (angle[i]*PI)/180;
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            double got = calastro.getMoonAge();
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln(testString);
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!(got>expectedAge-precision && got<expectedAge+precision)){
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: expected " + expectedAge +
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        " got " + got);
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }else{
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("PASS: expected " + expectedAge +
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        " got " + got);
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
387