|  | // © 2016 and later: Unicode, Inc. and others. | 
|  | // License & terms of use: http://www.unicode.org/copyright.html | 
|  | /******************************************************************** | 
|  | * COPYRIGHT: | 
|  | * Copyright (c) 1996-2016, International Business Machines Corporation and | 
|  | * others. All Rights Reserved. | 
|  | ********************************************************************/ | 
|  |  | 
|  | /* Test CalendarAstronomer for C++ */ | 
|  |  | 
|  | #include "unicode/utypes.h" | 
|  | #include "string.h" | 
|  | #include "unicode/locid.h" | 
|  |  | 
|  | #if !UCONFIG_NO_FORMATTING | 
|  |  | 
|  | #include "astro.h" | 
|  | #include "astrotst.h" | 
|  | #include "cmemory.h" | 
|  | #include "gregoimp.h" // for Math | 
|  | #include "unicode/simpletz.h" | 
|  |  | 
|  |  | 
|  | #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break | 
|  |  | 
|  | AstroTest::AstroTest(): astro(NULL), gc(NULL) { | 
|  | } | 
|  |  | 
|  | void AstroTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) | 
|  | { | 
|  | if (exec) logln("TestSuite AstroTest"); | 
|  | switch (index) { | 
|  | // CASE(0,FooTest); | 
|  | CASE(0,TestSolarLongitude); | 
|  | CASE(1,TestLunarPosition); | 
|  | CASE(2,TestCoordinates); | 
|  | CASE(3,TestCoverage); | 
|  | CASE(4,TestSunriseTimes); | 
|  | CASE(5,TestBasics); | 
|  | CASE(6,TestMoonAge); | 
|  | default: name = ""; break; | 
|  | } | 
|  | } | 
|  |  | 
|  | #undef CASE | 
|  |  | 
|  | #define ASSERT_OK(x) UPRV_BLOCK_MACRO_BEGIN { \ | 
|  | if(U_FAILURE(x)) { \ | 
|  | dataerrln("%s:%d: %s\n", __FILE__, __LINE__, u_errorName(x)); \ | 
|  | return; \ | 
|  | } \ | 
|  | } UPRV_BLOCK_MACRO_END | 
|  |  | 
|  |  | 
|  | void AstroTest::initAstro(UErrorCode &status) { | 
|  | if(U_FAILURE(status)) return; | 
|  |  | 
|  | if((astro != NULL) || (gc != NULL)) { | 
|  | dataerrln("Err: initAstro() called twice!"); | 
|  | closeAstro(status); | 
|  | if(U_SUCCESS(status)) { | 
|  | status = U_INTERNAL_PROGRAM_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | if(U_FAILURE(status)) return; | 
|  |  | 
|  | astro = new CalendarAstronomer(); | 
|  | gc = Calendar::createInstance(TimeZone::getGMT()->clone(), status); | 
|  | } | 
|  |  | 
|  | void AstroTest::closeAstro(UErrorCode &/*status*/) { | 
|  | if(astro != NULL) { | 
|  | delete astro; | 
|  | astro = NULL; | 
|  | } | 
|  | if(gc != NULL) { | 
|  | delete gc; | 
|  | gc = NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | void AstroTest::TestSolarLongitude(void) { | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | struct { | 
|  | int32_t d[5]; double f ; | 
|  | } tests[] = { | 
|  | { { 1980, 7, 27, 0, 00 },  124.114347 }, | 
|  | { { 1988, 7, 27, 00, 00 },  124.187732 } | 
|  | }; | 
|  |  | 
|  | logln(""); | 
|  | for (uint32_t i = 0; i < UPRV_LENGTHOF(tests); i++) { | 
|  | gc->clear(); | 
|  | gc->set(tests[i].d[0], tests[i].d[1]-1, tests[i].d[2], tests[i].d[3], tests[i].d[4]); | 
|  |  | 
|  | astro->setDate(gc->getTime(status)); | 
|  |  | 
|  | double longitude = astro->getSunLongitude(); | 
|  | //longitude = 0; | 
|  | CalendarAstronomer::Equatorial result; | 
|  | astro->getSunPosition(result); | 
|  | logln((UnicodeString)"Sun position is " + result.toString() + (UnicodeString)";  " /* + result.toHmsString()*/ + " Sun longitude is " + longitude ); | 
|  | } | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | void AstroTest::TestLunarPosition(void) { | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | static const double tests[][7] = { | 
|  | { 1979, 2, 26, 16, 00,  0, 0 } | 
|  | }; | 
|  | logln(""); | 
|  |  | 
|  | for (int32_t i = 0; i < UPRV_LENGTHOF(tests); i++) { | 
|  | gc->clear(); | 
|  | gc->set((int32_t)tests[i][0], (int32_t)tests[i][1]-1, (int32_t)tests[i][2], (int32_t)tests[i][3], (int32_t)tests[i][4]); | 
|  | astro->setDate(gc->getTime(status)); | 
|  |  | 
|  | const CalendarAstronomer::Equatorial& result = astro->getMoonPosition(); | 
|  | logln((UnicodeString)"Moon position is " + result.toString() + (UnicodeString)";  " /* + result->toHmsString()*/); | 
|  | } | 
|  |  | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | void AstroTest::TestCoordinates(void) { | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | CalendarAstronomer::Equatorial result; | 
|  | astro->eclipticToEquatorial(result, 139.686111 * CalendarAstronomer::PI / 180.0, 4.875278* CalendarAstronomer::PI / 180.0); | 
|  | logln((UnicodeString)"result is " + result.toString() + (UnicodeString)";  " /* + result.toHmsString()*/ ); | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | void AstroTest::TestCoverage(void) { | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | ASSERT_OK(status); | 
|  | GregorianCalendar *cal = new GregorianCalendar(1958, UCAL_AUGUST, 15,status); | 
|  | UDate then = cal->getTime(status); | 
|  | CalendarAstronomer *myastro = new CalendarAstronomer(then); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | //Latitude:  34 degrees 05' North | 
|  | //Longitude:  118 degrees 22' West | 
|  | double laLat = 34 + 5./60, laLong = 360 - (118 + 22./60); | 
|  | CalendarAstronomer *myastro2 = new CalendarAstronomer(laLong, laLat); | 
|  |  | 
|  | double eclLat = laLat * CalendarAstronomer::PI / 360; | 
|  | double eclLong = laLong * CalendarAstronomer::PI / 360; | 
|  |  | 
|  | CalendarAstronomer::Ecliptic ecl(eclLat, eclLong); | 
|  | CalendarAstronomer::Equatorial eq; | 
|  | CalendarAstronomer::Horizon hor; | 
|  |  | 
|  | logln("ecliptic: " + ecl.toString()); | 
|  | CalendarAstronomer *myastro3 = new CalendarAstronomer(); | 
|  | myastro3->setJulianDay((4713 + 2000) * 365.25); | 
|  |  | 
|  | CalendarAstronomer *astronomers[] = { | 
|  | myastro, myastro2, myastro3, myastro2 // check cache | 
|  | }; | 
|  |  | 
|  | for (uint32_t i = 0; i < UPRV_LENGTHOF(astronomers); ++i) { | 
|  | CalendarAstronomer *anAstro = astronomers[i]; | 
|  |  | 
|  | //logln("astro: " + astro); | 
|  | logln((UnicodeString)"   date: " + anAstro->getTime()); | 
|  | logln((UnicodeString)"   cent: " + anAstro->getJulianCentury()); | 
|  | logln((UnicodeString)"   gw sidereal: " + anAstro->getGreenwichSidereal()); | 
|  | logln((UnicodeString)"   loc sidereal: " + anAstro->getLocalSidereal()); | 
|  | logln((UnicodeString)"   equ ecl: " + (anAstro->eclipticToEquatorial(eq,ecl)).toString()); | 
|  | logln((UnicodeString)"   equ long: " + (anAstro->eclipticToEquatorial(eq, eclLong)).toString()); | 
|  | logln((UnicodeString)"   horiz: " + (anAstro->eclipticToHorizon(hor, eclLong)).toString()); | 
|  | logln((UnicodeString)"   sunrise: " + (anAstro->getSunRiseSet(TRUE))); | 
|  | logln((UnicodeString)"   sunset: " + (anAstro->getSunRiseSet(FALSE))); | 
|  | logln((UnicodeString)"   moon phase: " + anAstro->getMoonPhase()); | 
|  | logln((UnicodeString)"   moonrise: " + (anAstro->getMoonRiseSet(TRUE))); | 
|  | logln((UnicodeString)"   moonset: " + (anAstro->getMoonRiseSet(FALSE))); | 
|  | logln((UnicodeString)"   prev summer solstice: " + (anAstro->getSunTime(CalendarAstronomer::SUMMER_SOLSTICE(), FALSE))); | 
|  | logln((UnicodeString)"   next summer solstice: " + (anAstro->getSunTime(CalendarAstronomer::SUMMER_SOLSTICE(), TRUE))); | 
|  | logln((UnicodeString)"   prev full moon: " + (anAstro->getMoonTime(CalendarAstronomer::FULL_MOON(), FALSE))); | 
|  | logln((UnicodeString)"   next full moon: " + (anAstro->getMoonTime(CalendarAstronomer::FULL_MOON(), TRUE))); | 
|  | } | 
|  |  | 
|  | delete myastro2; | 
|  | delete myastro3; | 
|  | delete myastro; | 
|  | delete cal; | 
|  |  | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | void AstroTest::TestSunriseTimes(void) { | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | //  logln("Sunrise/Sunset times for San Jose, California, USA"); | 
|  | //  CalendarAstronomer *astro2 = new CalendarAstronomer(-121.55, 37.20); | 
|  | //  TimeZone *tz = TimeZone::createTimeZone("America/Los_Angeles"); | 
|  |  | 
|  | // We'll use a table generated by the UNSO website as our reference | 
|  | // From: http://aa.usno.navy.mil/ | 
|  | //-Location: W079 25, N43 40 | 
|  | //-Rise and Set for the Sun for 2001 | 
|  | //-Zone:  4h West of Greenwich | 
|  | int32_t USNO[] = { | 
|  | 6,59, 19,45, | 
|  | 6,57, 19,46, | 
|  | 6,56, 19,47, | 
|  | 6,54, 19,48, | 
|  | 6,52, 19,49, | 
|  | 6,50, 19,51, | 
|  | 6,48, 19,52, | 
|  | 6,47, 19,53, | 
|  | 6,45, 19,54, | 
|  | 6,43, 19,55, | 
|  | 6,42, 19,57, | 
|  | 6,40, 19,58, | 
|  | 6,38, 19,59, | 
|  | 6,36, 20, 0, | 
|  | 6,35, 20, 1, | 
|  | 6,33, 20, 3, | 
|  | 6,31, 20, 4, | 
|  | 6,30, 20, 5, | 
|  | 6,28, 20, 6, | 
|  | 6,27, 20, 7, | 
|  | 6,25, 20, 8, | 
|  | 6,23, 20,10, | 
|  | 6,22, 20,11, | 
|  | 6,20, 20,12, | 
|  | 6,19, 20,13, | 
|  | 6,17, 20,14, | 
|  | 6,16, 20,16, | 
|  | 6,14, 20,17, | 
|  | 6,13, 20,18, | 
|  | 6,11, 20,19, | 
|  | }; | 
|  |  | 
|  | logln("Sunrise/Sunset times for Toronto, Canada"); | 
|  | // long = 79 25", lat = 43 40" | 
|  | CalendarAstronomer astro3(-(79+25/60), 43+40/60); | 
|  |  | 
|  | // As of ICU4J 2.8 the ICU4J time zones implement pass-through | 
|  | // to the underlying JDK.  Because of variation in the | 
|  | // underlying JDKs, we have to use a fixed-offset | 
|  | // SimpleTimeZone to get consistent behavior between JDKs. | 
|  | // The offset we want is [-18000000, 3600000] (raw, dst). | 
|  | // [aliu 10/15/03] | 
|  |  | 
|  | // TimeZone tz = TimeZone.getTimeZone("America/Montreal"); | 
|  | SimpleTimeZone tz(-18000000 + 3600000, "Montreal(FIXED)"); | 
|  |  | 
|  | GregorianCalendar cal(tz.clone(), Locale::getUS(), status); | 
|  | GregorianCalendar cal2(tz.clone(), Locale::getUS(), status); | 
|  | cal.clear(); | 
|  | cal.set(UCAL_YEAR, 2001); | 
|  | cal.set(UCAL_MONTH, UCAL_APRIL); | 
|  | cal.set(UCAL_DAY_OF_MONTH, 1); | 
|  | cal.set(UCAL_HOUR_OF_DAY, 12); // must be near local noon for getSunRiseSet to work | 
|  |  | 
|  | LocalPointer<DateFormat> df_t(DateFormat::createTimeInstance(DateFormat::MEDIUM,Locale::getUS())); | 
|  | LocalPointer<DateFormat> df_d(DateFormat::createDateInstance(DateFormat::MEDIUM,Locale::getUS())); | 
|  | LocalPointer<DateFormat> df_dt(DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::MEDIUM, Locale::getUS())); | 
|  | if(!df_t.isValid() || !df_d.isValid() || !df_dt.isValid()) { | 
|  | dataerrln("couldn't create dateformats."); | 
|  | closeAstro(status); | 
|  | return; | 
|  | } | 
|  | df_t->adoptTimeZone(tz.clone()); | 
|  | df_d->adoptTimeZone(tz.clone()); | 
|  | df_dt->adoptTimeZone(tz.clone()); | 
|  |  | 
|  | for (int32_t i=0; i < 30; i++) { | 
|  | logln("setDate\n"); | 
|  | astro3.setDate(cal.getTime(status)); | 
|  | logln("getRiseSet(TRUE)\n"); | 
|  | UDate sunrise = astro3.getSunRiseSet(TRUE); | 
|  | logln("getRiseSet(FALSE)\n"); | 
|  | UDate sunset  = astro3.getSunRiseSet(FALSE); | 
|  | logln("end of getRiseSet\n"); | 
|  |  | 
|  | cal2.setTime(cal.getTime(status), status); | 
|  | cal2.set(UCAL_SECOND,      0); | 
|  | cal2.set(UCAL_MILLISECOND, 0); | 
|  |  | 
|  | cal2.set(UCAL_HOUR_OF_DAY, USNO[4*i+0]); | 
|  | cal2.set(UCAL_MINUTE,      USNO[4*i+1]); | 
|  | UDate exprise = cal2.getTime(status); | 
|  | cal2.set(UCAL_HOUR_OF_DAY, USNO[4*i+2]); | 
|  | cal2.set(UCAL_MINUTE,      USNO[4*i+3]); | 
|  | UDate expset = cal2.getTime(status); | 
|  | // Compute delta of what we got to the USNO data, in seconds | 
|  | int32_t deltarise = (int32_t)uprv_fabs((sunrise - exprise) / 1000); | 
|  | int32_t deltaset = (int32_t)uprv_fabs((sunset - expset) / 1000); | 
|  |  | 
|  | // Allow a deviation of 0..MAX_DEV seconds | 
|  | // It would be nice to get down to 60 seconds, but at this | 
|  | // point that appears to be impossible without a redo of the | 
|  | // algorithm using something more advanced than Duffett-Smith. | 
|  | int32_t MAX_DEV = 180; | 
|  | UnicodeString s1, s2, s3, s4, s5; | 
|  | if (deltarise > MAX_DEV || deltaset > MAX_DEV) { | 
|  | if (deltarise > MAX_DEV) { | 
|  | errln("FAIL: (rise) " + df_d->format(cal.getTime(status),s1) + | 
|  | ", Sunrise: " + df_dt->format(sunrise, s2) + | 
|  | " (USNO " + df_t->format(exprise,s3) + | 
|  | " d=" + deltarise + "s)"); | 
|  | } else { | 
|  | logln(df_d->format(cal.getTime(status),s1) + | 
|  | ", Sunrise: " + df_dt->format(sunrise,s2) + | 
|  | " (USNO " + df_t->format(exprise,s3) + ")"); | 
|  | } | 
|  | s1.remove(); s2.remove(); s3.remove(); s4.remove(); s5.remove(); | 
|  | if (deltaset > MAX_DEV) { | 
|  | errln("FAIL: (set)  " + df_d->format(cal.getTime(status),s1) + | 
|  | ", Sunset:  " + df_dt->format(sunset,s2) + | 
|  | " (USNO " + df_t->format(expset,s3) + | 
|  | " d=" + deltaset + "s)"); | 
|  | } else { | 
|  | logln(df_d->format(cal.getTime(status),s1) + | 
|  | ", Sunset: " + df_dt->format(sunset,s2) + | 
|  | " (USNO " + df_t->format(expset,s3) + ")"); | 
|  | } | 
|  | } else { | 
|  | logln(df_d->format(cal.getTime(status),s1) + | 
|  | ", Sunrise: " + df_dt->format(sunrise,s2) + | 
|  | " (USNO " + df_t->format(exprise,s3) + ")" + | 
|  | ", Sunset: " + df_dt->format(sunset,s4) + | 
|  | " (USNO " + df_t->format(expset,s5) + ")"); | 
|  | } | 
|  | cal.add(UCAL_DATE, 1, status); | 
|  | } | 
|  |  | 
|  | //        CalendarAstronomer a = new CalendarAstronomer(-(71+5/60), 42+37/60); | 
|  | //        cal.clear(); | 
|  | //        cal.set(cal.YEAR, 1986); | 
|  | //        cal.set(cal.MONTH, cal.MARCH); | 
|  | //        cal.set(cal.DATE, 10); | 
|  | //        cal.set(cal.YEAR, 1988); | 
|  | //        cal.set(cal.MONTH, cal.JULY); | 
|  | //        cal.set(cal.DATE, 27); | 
|  | //        a.setDate(cal.getTime()); | 
|  | //        long r = a.getSunRiseSet2(true); | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | void AstroTest::TestBasics(void) { | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | if (U_FAILURE(status)) { | 
|  | dataerrln("Got error: %s", u_errorName(status)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Check that our JD computation is the same as the book's (p. 88) | 
|  | GregorianCalendar cal3(TimeZone::getGMT()->clone(), Locale::getUS(), status); | 
|  | LocalPointer<DateFormat> d3(DateFormat::createDateTimeInstance(DateFormat::MEDIUM,DateFormat::MEDIUM,Locale::getUS())); | 
|  | if (d3.isNull()) { | 
|  | dataerrln("Got error: %s", u_errorName(status)); | 
|  | closeAstro(status); | 
|  | return; | 
|  | } | 
|  | d3->setTimeZone(*TimeZone::getGMT()); | 
|  | cal3.clear(); | 
|  | cal3.set(UCAL_YEAR, 1980); | 
|  | cal3.set(UCAL_MONTH, UCAL_JULY); | 
|  | cal3.set(UCAL_DATE, 2); | 
|  | logln("cal3[a]=%.1lf, d=%d\n", cal3.getTime(status), cal3.get(UCAL_JULIAN_DAY,status)); | 
|  | { | 
|  | UnicodeString s; | 
|  | logln(UnicodeString("cal3[a] = ") + d3->format(cal3.getTime(status),s)); | 
|  | } | 
|  | cal3.clear(); | 
|  | cal3.set(UCAL_YEAR, 1980); | 
|  | cal3.set(UCAL_MONTH, UCAL_JULY); | 
|  | cal3.set(UCAL_DATE, 27); | 
|  | logln("cal3=%.1lf, d=%d\n", cal3.getTime(status), cal3.get(UCAL_JULIAN_DAY,status)); | 
|  |  | 
|  | ASSERT_OK(status); | 
|  | { | 
|  | UnicodeString s; | 
|  | logln(UnicodeString("cal3 = ") + d3->format(cal3.getTime(status),s)); | 
|  | } | 
|  | astro->setTime(cal3.getTime(status)); | 
|  | double jd = astro->getJulianDay() - 2447891.5; | 
|  | double exp = -3444.; | 
|  | if (jd == exp) { | 
|  | UnicodeString s; | 
|  | logln(d3->format(cal3.getTime(status),s) + " => " + jd); | 
|  | } else { | 
|  | UnicodeString s; | 
|  | errln("FAIL: " + d3->format(cal3.getTime(status), s) + " => " + jd + | 
|  | ", expected " + exp); | 
|  | } | 
|  |  | 
|  | //        cal3.clear(); | 
|  | //        cal3.set(cal3.YEAR, 1990); | 
|  | //        cal3.set(cal3.MONTH, Calendar.JANUARY); | 
|  | //        cal3.set(cal3.DATE, 1); | 
|  | //        cal3.add(cal3.DATE, -1); | 
|  | //        astro.setDate(cal3.getTime()); | 
|  | //        astro.foo(); | 
|  |  | 
|  | ASSERT_OK(status); | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | } | 
|  |  | 
|  | void AstroTest::TestMoonAge(void){ | 
|  | UErrorCode status = U_ZERO_ERROR; | 
|  | initAstro(status); | 
|  | ASSERT_OK(status); | 
|  |  | 
|  | // more testcases are around the date 05/20/2012 | 
|  | //ticket#3785  UDate ud0 = 1337557623000.0; | 
|  | static const double testcase[][10] = {{2012, 5, 20 , 16 , 48, 59}, | 
|  | {2012, 5, 20 , 16 , 47, 34}, | 
|  | {2012, 5, 21, 00, 00, 00}, | 
|  | {2012, 5, 20, 14, 55, 59}, | 
|  | {2012, 5, 21, 7, 40, 40}, | 
|  | {2023, 9, 25, 10,00, 00}, | 
|  | {2008, 7, 7, 15, 00, 33}, | 
|  | {1832, 9, 24, 2, 33, 41 }, | 
|  | {2016, 1, 31, 23, 59, 59}, | 
|  | {2099, 5, 20, 14, 55, 59} | 
|  | }; | 
|  | // Moon phase angle - Got from http://www.moonsystem.to/checkupe.htm | 
|  | static const double angle[] = {356.8493418421329, 356.8386760059673, 0.09625415252237701, 355.9986960782416, 3.5714026601303317, 124.26906744384183, 59.80247650195558, | 
|  | 357.54163205513123, 268.41779281511094, 4.82340276581624}; | 
|  | static const double precision = CalendarAstronomer::PI/32; | 
|  | for (int32_t i = 0; i < UPRV_LENGTHOF(testcase); i++) { | 
|  | gc->clear(); | 
|  | logln((UnicodeString)"CASE["+i+"]: Year "+(int32_t)testcase[i][0]+" Month "+(int32_t)testcase[i][1]+" Day "+ | 
|  | (int32_t)testcase[i][2]+" Hour "+(int32_t)testcase[i][3]+" Minutes "+(int32_t)testcase[i][4]+ | 
|  | " Seconds "+(int32_t)testcase[i][5]); | 
|  | gc->set((int32_t)testcase[i][0], (int32_t)testcase[i][1]-1, (int32_t)testcase[i][2], (int32_t)testcase[i][3], (int32_t)testcase[i][4], (int32_t)testcase[i][5]); | 
|  | astro->setDate(gc->getTime(status)); | 
|  | double expectedAge = (angle[i]*CalendarAstronomer::PI)/180; | 
|  | double got = astro->getMoonAge(); | 
|  | //logln(testString); | 
|  | if(!(got>expectedAge-precision && got<expectedAge+precision)){ | 
|  | errln((UnicodeString)"FAIL: expected " + expectedAge + | 
|  | " got " + got); | 
|  | }else{ | 
|  | logln((UnicodeString)"PASS: expected " + expectedAge + | 
|  | " got " + got); | 
|  | } | 
|  | } | 
|  | closeAstro(status); | 
|  | ASSERT_OK(status); | 
|  | } | 
|  |  | 
|  |  | 
|  | // TODO: try finding next new moon after  07/28/1984 16:00 GMT | 
|  |  | 
|  |  | 
|  | #endif | 
|  |  | 
|  |  | 
|  |  |