12e5b6d6dSopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci/********************************************************************
42e5b6d6dSopenharmony_ci * COPYRIGHT:
52e5b6d6dSopenharmony_ci * Copyright (c) 1996-2016, International Business Machines Corporation and
62e5b6d6dSopenharmony_ci * others. All Rights Reserved.
72e5b6d6dSopenharmony_ci ********************************************************************/
82e5b6d6dSopenharmony_ci
92e5b6d6dSopenharmony_ci/* Test CalendarAstronomer for C++ */
102e5b6d6dSopenharmony_ci
112e5b6d6dSopenharmony_ci#include "unicode/utypes.h"
122e5b6d6dSopenharmony_ci#include "string.h"
132e5b6d6dSopenharmony_ci#include "unicode/locid.h"
142e5b6d6dSopenharmony_ci
152e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
162e5b6d6dSopenharmony_ci
172e5b6d6dSopenharmony_ci#include "astro.h"
182e5b6d6dSopenharmony_ci#include "astrotst.h"
192e5b6d6dSopenharmony_ci#include "cmemory.h"
202e5b6d6dSopenharmony_ci#include "gregoimp.h" // for Math
212e5b6d6dSopenharmony_ci#include "unicode/simpletz.h"
222e5b6d6dSopenharmony_ci
232e5b6d6dSopenharmony_ci
242e5b6d6dSopenharmony_ci#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
252e5b6d6dSopenharmony_ci
262e5b6d6dSopenharmony_ciAstroTest::AstroTest(): astro(NULL), gc(NULL) {
272e5b6d6dSopenharmony_ci}
282e5b6d6dSopenharmony_ci
292e5b6d6dSopenharmony_civoid AstroTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
302e5b6d6dSopenharmony_ci{
312e5b6d6dSopenharmony_ci    if (exec) logln("TestSuite AstroTest");
322e5b6d6dSopenharmony_ci    switch (index) {
332e5b6d6dSopenharmony_ci      // CASE(0,FooTest);
342e5b6d6dSopenharmony_ci      CASE(0,TestSolarLongitude);
352e5b6d6dSopenharmony_ci      CASE(1,TestLunarPosition);
362e5b6d6dSopenharmony_ci      CASE(2,TestCoordinates);
372e5b6d6dSopenharmony_ci      CASE(3,TestCoverage);
382e5b6d6dSopenharmony_ci      CASE(4,TestSunriseTimes);
392e5b6d6dSopenharmony_ci      CASE(5,TestBasics);
402e5b6d6dSopenharmony_ci      CASE(6,TestMoonAge);
412e5b6d6dSopenharmony_ci    default: name = ""; break;
422e5b6d6dSopenharmony_ci    }
432e5b6d6dSopenharmony_ci}
442e5b6d6dSopenharmony_ci
452e5b6d6dSopenharmony_ci#undef CASE
462e5b6d6dSopenharmony_ci
472e5b6d6dSopenharmony_ci#define ASSERT_OK(x) UPRV_BLOCK_MACRO_BEGIN { \
482e5b6d6dSopenharmony_ci    if(U_FAILURE(x)) { \
492e5b6d6dSopenharmony_ci        dataerrln("%s:%d: %s\n", __FILE__, __LINE__, u_errorName(x)); \
502e5b6d6dSopenharmony_ci        return; \
512e5b6d6dSopenharmony_ci    } \
522e5b6d6dSopenharmony_ci} UPRV_BLOCK_MACRO_END
532e5b6d6dSopenharmony_ci
542e5b6d6dSopenharmony_ci
552e5b6d6dSopenharmony_civoid AstroTest::initAstro(UErrorCode &status) {
562e5b6d6dSopenharmony_ci  if(U_FAILURE(status)) return;
572e5b6d6dSopenharmony_ci
582e5b6d6dSopenharmony_ci  if((astro != NULL) || (gc != NULL)) {
592e5b6d6dSopenharmony_ci    dataerrln("Err: initAstro() called twice!");
602e5b6d6dSopenharmony_ci    closeAstro(status);
612e5b6d6dSopenharmony_ci    if(U_SUCCESS(status)) {
622e5b6d6dSopenharmony_ci      status = U_INTERNAL_PROGRAM_ERROR;
632e5b6d6dSopenharmony_ci    }
642e5b6d6dSopenharmony_ci  }
652e5b6d6dSopenharmony_ci
662e5b6d6dSopenharmony_ci  if(U_FAILURE(status)) return;
672e5b6d6dSopenharmony_ci
682e5b6d6dSopenharmony_ci  astro = new CalendarAstronomer();
692e5b6d6dSopenharmony_ci  gc = Calendar::createInstance(TimeZone::getGMT()->clone(), status);
702e5b6d6dSopenharmony_ci}
712e5b6d6dSopenharmony_ci
722e5b6d6dSopenharmony_civoid AstroTest::closeAstro(UErrorCode &/*status*/) {
732e5b6d6dSopenharmony_ci  if(astro != NULL) {
742e5b6d6dSopenharmony_ci    delete astro;
752e5b6d6dSopenharmony_ci    astro = NULL;
762e5b6d6dSopenharmony_ci  }
772e5b6d6dSopenharmony_ci  if(gc != NULL) {
782e5b6d6dSopenharmony_ci    delete gc;
792e5b6d6dSopenharmony_ci    gc = NULL;
802e5b6d6dSopenharmony_ci  }
812e5b6d6dSopenharmony_ci}
822e5b6d6dSopenharmony_ci
832e5b6d6dSopenharmony_civoid AstroTest::TestSolarLongitude(void) {
842e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
852e5b6d6dSopenharmony_ci  initAstro(status);
862e5b6d6dSopenharmony_ci  ASSERT_OK(status);
872e5b6d6dSopenharmony_ci
882e5b6d6dSopenharmony_ci  struct {
892e5b6d6dSopenharmony_ci    int32_t d[5]; double f ;
902e5b6d6dSopenharmony_ci  } tests[] = {
912e5b6d6dSopenharmony_ci    { { 1980, 7, 27, 0, 00 },  124.114347 },
922e5b6d6dSopenharmony_ci    { { 1988, 7, 27, 00, 00 },  124.187732 }
932e5b6d6dSopenharmony_ci  };
942e5b6d6dSopenharmony_ci
952e5b6d6dSopenharmony_ci  logln("");
962e5b6d6dSopenharmony_ci  for (uint32_t i = 0; i < UPRV_LENGTHOF(tests); i++) {
972e5b6d6dSopenharmony_ci    gc->clear();
982e5b6d6dSopenharmony_ci    gc->set(tests[i].d[0], tests[i].d[1]-1, tests[i].d[2], tests[i].d[3], tests[i].d[4]);
992e5b6d6dSopenharmony_ci
1002e5b6d6dSopenharmony_ci    astro->setDate(gc->getTime(status));
1012e5b6d6dSopenharmony_ci
1022e5b6d6dSopenharmony_ci    double longitude = astro->getSunLongitude();
1032e5b6d6dSopenharmony_ci    //longitude = 0;
1042e5b6d6dSopenharmony_ci    CalendarAstronomer::Equatorial result;
1052e5b6d6dSopenharmony_ci    astro->getSunPosition(result);
1062e5b6d6dSopenharmony_ci    logln((UnicodeString)"Sun position is " + result.toString() + (UnicodeString)";  " /* + result.toHmsString()*/ + " Sun longitude is " + longitude );
1072e5b6d6dSopenharmony_ci  }
1082e5b6d6dSopenharmony_ci  closeAstro(status);
1092e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1102e5b6d6dSopenharmony_ci}
1112e5b6d6dSopenharmony_ci
1122e5b6d6dSopenharmony_ci
1132e5b6d6dSopenharmony_ci
1142e5b6d6dSopenharmony_civoid AstroTest::TestLunarPosition(void) {
1152e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
1162e5b6d6dSopenharmony_ci  initAstro(status);
1172e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1182e5b6d6dSopenharmony_ci
1192e5b6d6dSopenharmony_ci  static const double tests[][7] = {
1202e5b6d6dSopenharmony_ci    { 1979, 2, 26, 16, 00,  0, 0 }
1212e5b6d6dSopenharmony_ci  };
1222e5b6d6dSopenharmony_ci  logln("");
1232e5b6d6dSopenharmony_ci
1242e5b6d6dSopenharmony_ci  for (int32_t i = 0; i < UPRV_LENGTHOF(tests); i++) {
1252e5b6d6dSopenharmony_ci    gc->clear();
1262e5b6d6dSopenharmony_ci    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]);
1272e5b6d6dSopenharmony_ci    astro->setDate(gc->getTime(status));
1282e5b6d6dSopenharmony_ci
1292e5b6d6dSopenharmony_ci    const CalendarAstronomer::Equatorial& result = astro->getMoonPosition();
1302e5b6d6dSopenharmony_ci    logln((UnicodeString)"Moon position is " + result.toString() + (UnicodeString)";  " /* + result->toHmsString()*/);
1312e5b6d6dSopenharmony_ci  }
1322e5b6d6dSopenharmony_ci
1332e5b6d6dSopenharmony_ci  closeAstro(status);
1342e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1352e5b6d6dSopenharmony_ci}
1362e5b6d6dSopenharmony_ci
1372e5b6d6dSopenharmony_ci
1382e5b6d6dSopenharmony_ci
1392e5b6d6dSopenharmony_civoid AstroTest::TestCoordinates(void) {
1402e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
1412e5b6d6dSopenharmony_ci  initAstro(status);
1422e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1432e5b6d6dSopenharmony_ci
1442e5b6d6dSopenharmony_ci  CalendarAstronomer::Equatorial result;
1452e5b6d6dSopenharmony_ci  astro->eclipticToEquatorial(result, 139.686111 * CalendarAstronomer::PI / 180.0, 4.875278* CalendarAstronomer::PI / 180.0);
1462e5b6d6dSopenharmony_ci  logln((UnicodeString)"result is " + result.toString() + (UnicodeString)";  " /* + result.toHmsString()*/ );
1472e5b6d6dSopenharmony_ci  closeAstro(status);
1482e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1492e5b6d6dSopenharmony_ci}
1502e5b6d6dSopenharmony_ci
1512e5b6d6dSopenharmony_ci
1522e5b6d6dSopenharmony_ci
1532e5b6d6dSopenharmony_civoid AstroTest::TestCoverage(void) {
1542e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
1552e5b6d6dSopenharmony_ci  initAstro(status);
1562e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1572e5b6d6dSopenharmony_ci  GregorianCalendar *cal = new GregorianCalendar(1958, UCAL_AUGUST, 15,status);
1582e5b6d6dSopenharmony_ci  UDate then = cal->getTime(status);
1592e5b6d6dSopenharmony_ci  CalendarAstronomer *myastro = new CalendarAstronomer(then);
1602e5b6d6dSopenharmony_ci  ASSERT_OK(status);
1612e5b6d6dSopenharmony_ci
1622e5b6d6dSopenharmony_ci  //Latitude:  34 degrees 05' North
1632e5b6d6dSopenharmony_ci  //Longitude:  118 degrees 22' West
1642e5b6d6dSopenharmony_ci  double laLat = 34 + 5./60, laLong = 360 - (118 + 22./60);
1652e5b6d6dSopenharmony_ci  CalendarAstronomer *myastro2 = new CalendarAstronomer(laLong, laLat);
1662e5b6d6dSopenharmony_ci
1672e5b6d6dSopenharmony_ci  double eclLat = laLat * CalendarAstronomer::PI / 360;
1682e5b6d6dSopenharmony_ci  double eclLong = laLong * CalendarAstronomer::PI / 360;
1692e5b6d6dSopenharmony_ci
1702e5b6d6dSopenharmony_ci  CalendarAstronomer::Ecliptic ecl(eclLat, eclLong);
1712e5b6d6dSopenharmony_ci  CalendarAstronomer::Equatorial eq;
1722e5b6d6dSopenharmony_ci  CalendarAstronomer::Horizon hor;
1732e5b6d6dSopenharmony_ci
1742e5b6d6dSopenharmony_ci  logln("ecliptic: " + ecl.toString());
1752e5b6d6dSopenharmony_ci  CalendarAstronomer *myastro3 = new CalendarAstronomer();
1762e5b6d6dSopenharmony_ci  myastro3->setJulianDay((4713 + 2000) * 365.25);
1772e5b6d6dSopenharmony_ci
1782e5b6d6dSopenharmony_ci  CalendarAstronomer *astronomers[] = {
1792e5b6d6dSopenharmony_ci    myastro, myastro2, myastro3, myastro2 // check cache
1802e5b6d6dSopenharmony_ci  };
1812e5b6d6dSopenharmony_ci
1822e5b6d6dSopenharmony_ci  for (uint32_t i = 0; i < UPRV_LENGTHOF(astronomers); ++i) {
1832e5b6d6dSopenharmony_ci    CalendarAstronomer *anAstro = astronomers[i];
1842e5b6d6dSopenharmony_ci
1852e5b6d6dSopenharmony_ci    //logln("astro: " + astro);
1862e5b6d6dSopenharmony_ci    logln((UnicodeString)"   date: " + anAstro->getTime());
1872e5b6d6dSopenharmony_ci    logln((UnicodeString)"   cent: " + anAstro->getJulianCentury());
1882e5b6d6dSopenharmony_ci    logln((UnicodeString)"   gw sidereal: " + anAstro->getGreenwichSidereal());
1892e5b6d6dSopenharmony_ci    logln((UnicodeString)"   loc sidereal: " + anAstro->getLocalSidereal());
1902e5b6d6dSopenharmony_ci    logln((UnicodeString)"   equ ecl: " + (anAstro->eclipticToEquatorial(eq,ecl)).toString());
1912e5b6d6dSopenharmony_ci    logln((UnicodeString)"   equ long: " + (anAstro->eclipticToEquatorial(eq, eclLong)).toString());
1922e5b6d6dSopenharmony_ci    logln((UnicodeString)"   horiz: " + (anAstro->eclipticToHorizon(hor, eclLong)).toString());
1932e5b6d6dSopenharmony_ci    logln((UnicodeString)"   sunrise: " + (anAstro->getSunRiseSet(true)));
1942e5b6d6dSopenharmony_ci    logln((UnicodeString)"   sunset: " + (anAstro->getSunRiseSet(false)));
1952e5b6d6dSopenharmony_ci    logln((UnicodeString)"   moon phase: " + anAstro->getMoonPhase());
1962e5b6d6dSopenharmony_ci    logln((UnicodeString)"   moonrise: " + (anAstro->getMoonRiseSet(true)));
1972e5b6d6dSopenharmony_ci    logln((UnicodeString)"   moonset: " + (anAstro->getMoonRiseSet(false)));
1982e5b6d6dSopenharmony_ci    logln((UnicodeString)"   prev summer solstice: " + (anAstro->getSunTime(CalendarAstronomer::SUMMER_SOLSTICE(), false)));
1992e5b6d6dSopenharmony_ci    logln((UnicodeString)"   next summer solstice: " + (anAstro->getSunTime(CalendarAstronomer::SUMMER_SOLSTICE(), true)));
2002e5b6d6dSopenharmony_ci    logln((UnicodeString)"   prev full moon: " + (anAstro->getMoonTime(CalendarAstronomer::FULL_MOON(), false)));
2012e5b6d6dSopenharmony_ci    logln((UnicodeString)"   next full moon: " + (anAstro->getMoonTime(CalendarAstronomer::FULL_MOON(), true)));
2022e5b6d6dSopenharmony_ci  }
2032e5b6d6dSopenharmony_ci
2042e5b6d6dSopenharmony_ci  delete myastro2;
2052e5b6d6dSopenharmony_ci  delete myastro3;
2062e5b6d6dSopenharmony_ci  delete myastro;
2072e5b6d6dSopenharmony_ci  delete cal;
2082e5b6d6dSopenharmony_ci
2092e5b6d6dSopenharmony_ci  closeAstro(status);
2102e5b6d6dSopenharmony_ci  ASSERT_OK(status);
2112e5b6d6dSopenharmony_ci}
2122e5b6d6dSopenharmony_ci
2132e5b6d6dSopenharmony_ci
2142e5b6d6dSopenharmony_ci
2152e5b6d6dSopenharmony_civoid AstroTest::TestSunriseTimes(void) {
2162e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
2172e5b6d6dSopenharmony_ci  initAstro(status);
2182e5b6d6dSopenharmony_ci  ASSERT_OK(status);
2192e5b6d6dSopenharmony_ci
2202e5b6d6dSopenharmony_ci  //  logln("Sunrise/Sunset times for San Jose, California, USA");
2212e5b6d6dSopenharmony_ci  //  CalendarAstronomer *astro2 = new CalendarAstronomer(-121.55, 37.20);
2222e5b6d6dSopenharmony_ci  //  TimeZone *tz = TimeZone::createTimeZone("America/Los_Angeles");
2232e5b6d6dSopenharmony_ci
2242e5b6d6dSopenharmony_ci  // We'll use a table generated by the UNSO website as our reference
2252e5b6d6dSopenharmony_ci  // From: http://aa.usno.navy.mil/
2262e5b6d6dSopenharmony_ci  //-Location: W079 25, N43 40
2272e5b6d6dSopenharmony_ci  //-Rise and Set for the Sun for 2001
2282e5b6d6dSopenharmony_ci  //-Zone:  4h West of Greenwich
2292e5b6d6dSopenharmony_ci  int32_t USNO[] = {
2302e5b6d6dSopenharmony_ci    6,59, 19,45,
2312e5b6d6dSopenharmony_ci    6,57, 19,46,
2322e5b6d6dSopenharmony_ci    6,56, 19,47,
2332e5b6d6dSopenharmony_ci    6,54, 19,48,
2342e5b6d6dSopenharmony_ci    6,52, 19,49,
2352e5b6d6dSopenharmony_ci    6,50, 19,51,
2362e5b6d6dSopenharmony_ci    6,48, 19,52,
2372e5b6d6dSopenharmony_ci    6,47, 19,53,
2382e5b6d6dSopenharmony_ci    6,45, 19,54,
2392e5b6d6dSopenharmony_ci    6,43, 19,55,
2402e5b6d6dSopenharmony_ci    6,42, 19,57,
2412e5b6d6dSopenharmony_ci    6,40, 19,58,
2422e5b6d6dSopenharmony_ci    6,38, 19,59,
2432e5b6d6dSopenharmony_ci    6,36, 20, 0,
2442e5b6d6dSopenharmony_ci    6,35, 20, 1,
2452e5b6d6dSopenharmony_ci    6,33, 20, 3,
2462e5b6d6dSopenharmony_ci    6,31, 20, 4,
2472e5b6d6dSopenharmony_ci    6,30, 20, 5,
2482e5b6d6dSopenharmony_ci    6,28, 20, 6,
2492e5b6d6dSopenharmony_ci    6,27, 20, 7,
2502e5b6d6dSopenharmony_ci    6,25, 20, 8,
2512e5b6d6dSopenharmony_ci    6,23, 20,10,
2522e5b6d6dSopenharmony_ci    6,22, 20,11,
2532e5b6d6dSopenharmony_ci    6,20, 20,12,
2542e5b6d6dSopenharmony_ci    6,19, 20,13,
2552e5b6d6dSopenharmony_ci    6,17, 20,14,
2562e5b6d6dSopenharmony_ci    6,16, 20,16,
2572e5b6d6dSopenharmony_ci    6,14, 20,17,
2582e5b6d6dSopenharmony_ci    6,13, 20,18,
2592e5b6d6dSopenharmony_ci    6,11, 20,19,
2602e5b6d6dSopenharmony_ci  };
2612e5b6d6dSopenharmony_ci
2622e5b6d6dSopenharmony_ci  logln("Sunrise/Sunset times for Toronto, Canada");
2632e5b6d6dSopenharmony_ci  // long = 79 25", lat = 43 40"
2642e5b6d6dSopenharmony_ci  CalendarAstronomer astro3(-(79+25/60), 43+40/60);
2652e5b6d6dSopenharmony_ci
2662e5b6d6dSopenharmony_ci  // As of ICU4J 2.8 the ICU4J time zones implement pass-through
2672e5b6d6dSopenharmony_ci  // to the underlying JDK.  Because of variation in the
2682e5b6d6dSopenharmony_ci  // underlying JDKs, we have to use a fixed-offset
2692e5b6d6dSopenharmony_ci  // SimpleTimeZone to get consistent behavior between JDKs.
2702e5b6d6dSopenharmony_ci  // The offset we want is [-18000000, 3600000] (raw, dst).
2712e5b6d6dSopenharmony_ci  // [aliu 10/15/03]
2722e5b6d6dSopenharmony_ci
2732e5b6d6dSopenharmony_ci  // TimeZone tz = TimeZone.getTimeZone("America/Montreal");
2742e5b6d6dSopenharmony_ci  SimpleTimeZone tz(-18000000 + 3600000, "Montreal(FIXED)");
2752e5b6d6dSopenharmony_ci
2762e5b6d6dSopenharmony_ci  GregorianCalendar cal(tz.clone(), Locale::getUS(), status);
2772e5b6d6dSopenharmony_ci  GregorianCalendar cal2(tz.clone(), Locale::getUS(), status);
2782e5b6d6dSopenharmony_ci  cal.clear();
2792e5b6d6dSopenharmony_ci  cal.set(UCAL_YEAR, 2001);
2802e5b6d6dSopenharmony_ci  cal.set(UCAL_MONTH, UCAL_APRIL);
2812e5b6d6dSopenharmony_ci  cal.set(UCAL_DAY_OF_MONTH, 1);
2822e5b6d6dSopenharmony_ci  cal.set(UCAL_HOUR_OF_DAY, 12); // must be near local noon for getSunRiseSet to work
2832e5b6d6dSopenharmony_ci
2842e5b6d6dSopenharmony_ci  LocalPointer<DateFormat> df_t(DateFormat::createTimeInstance(DateFormat::MEDIUM,Locale::getUS()));
2852e5b6d6dSopenharmony_ci  LocalPointer<DateFormat> df_d(DateFormat::createDateInstance(DateFormat::MEDIUM,Locale::getUS()));
2862e5b6d6dSopenharmony_ci  LocalPointer<DateFormat> df_dt(DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::MEDIUM, Locale::getUS()));
2872e5b6d6dSopenharmony_ci  if(!df_t.isValid() || !df_d.isValid() || !df_dt.isValid()) {
2882e5b6d6dSopenharmony_ci      dataerrln("couldn't create dateformats.");
2892e5b6d6dSopenharmony_ci      closeAstro(status);
2902e5b6d6dSopenharmony_ci      return;
2912e5b6d6dSopenharmony_ci  }
2922e5b6d6dSopenharmony_ci  df_t->adoptTimeZone(tz.clone());
2932e5b6d6dSopenharmony_ci  df_d->adoptTimeZone(tz.clone());
2942e5b6d6dSopenharmony_ci  df_dt->adoptTimeZone(tz.clone());
2952e5b6d6dSopenharmony_ci
2962e5b6d6dSopenharmony_ci  for (int32_t i=0; i < 30; i++) {
2972e5b6d6dSopenharmony_ci    logln("setDate\n");
2982e5b6d6dSopenharmony_ci    astro3.setDate(cal.getTime(status));
2992e5b6d6dSopenharmony_ci    logln("getRiseSet(true)\n");
3002e5b6d6dSopenharmony_ci    UDate sunrise = astro3.getSunRiseSet(true);
3012e5b6d6dSopenharmony_ci    logln("getRiseSet(false)\n");
3022e5b6d6dSopenharmony_ci    UDate sunset  = astro3.getSunRiseSet(false);
3032e5b6d6dSopenharmony_ci    logln("end of getRiseSet\n");
3042e5b6d6dSopenharmony_ci
3052e5b6d6dSopenharmony_ci    cal2.setTime(cal.getTime(status), status);
3062e5b6d6dSopenharmony_ci    cal2.set(UCAL_SECOND,      0);
3072e5b6d6dSopenharmony_ci    cal2.set(UCAL_MILLISECOND, 0);
3082e5b6d6dSopenharmony_ci
3092e5b6d6dSopenharmony_ci    cal2.set(UCAL_HOUR_OF_DAY, USNO[4*i+0]);
3102e5b6d6dSopenharmony_ci    cal2.set(UCAL_MINUTE,      USNO[4*i+1]);
3112e5b6d6dSopenharmony_ci    UDate exprise = cal2.getTime(status);
3122e5b6d6dSopenharmony_ci    cal2.set(UCAL_HOUR_OF_DAY, USNO[4*i+2]);
3132e5b6d6dSopenharmony_ci    cal2.set(UCAL_MINUTE,      USNO[4*i+3]);
3142e5b6d6dSopenharmony_ci    UDate expset = cal2.getTime(status);
3152e5b6d6dSopenharmony_ci    // Compute delta of what we got to the USNO data, in seconds
3162e5b6d6dSopenharmony_ci    int32_t deltarise = (int32_t)uprv_fabs((sunrise - exprise) / 1000);
3172e5b6d6dSopenharmony_ci    int32_t deltaset = (int32_t)uprv_fabs((sunset - expset) / 1000);
3182e5b6d6dSopenharmony_ci
3192e5b6d6dSopenharmony_ci    // Allow a deviation of 0..MAX_DEV seconds
3202e5b6d6dSopenharmony_ci    // It would be nice to get down to 60 seconds, but at this
3212e5b6d6dSopenharmony_ci    // point that appears to be impossible without a redo of the
3222e5b6d6dSopenharmony_ci    // algorithm using something more advanced than Duffett-Smith.
3232e5b6d6dSopenharmony_ci    int32_t MAX_DEV = 180;
3242e5b6d6dSopenharmony_ci    UnicodeString s1, s2, s3, s4, s5;
3252e5b6d6dSopenharmony_ci    if (deltarise > MAX_DEV || deltaset > MAX_DEV) {
3262e5b6d6dSopenharmony_ci      if (deltarise > MAX_DEV) {
3272e5b6d6dSopenharmony_ci        errln("FAIL: (rise) " + df_d->format(cal.getTime(status),s1) +
3282e5b6d6dSopenharmony_ci              ", Sunrise: " + df_dt->format(sunrise, s2) +
3292e5b6d6dSopenharmony_ci              " (USNO " + df_t->format(exprise,s3) +
3302e5b6d6dSopenharmony_ci              " d=" + deltarise + "s)");
3312e5b6d6dSopenharmony_ci      } else {
3322e5b6d6dSopenharmony_ci        logln(df_d->format(cal.getTime(status),s1) +
3332e5b6d6dSopenharmony_ci              ", Sunrise: " + df_dt->format(sunrise,s2) +
3342e5b6d6dSopenharmony_ci              " (USNO " + df_t->format(exprise,s3) + ")");
3352e5b6d6dSopenharmony_ci      }
3362e5b6d6dSopenharmony_ci      s1.remove(); s2.remove(); s3.remove(); s4.remove(); s5.remove();
3372e5b6d6dSopenharmony_ci      if (deltaset > MAX_DEV) {
3382e5b6d6dSopenharmony_ci        errln("FAIL: (set)  " + df_d->format(cal.getTime(status),s1) +
3392e5b6d6dSopenharmony_ci              ", Sunset:  " + df_dt->format(sunset,s2) +
3402e5b6d6dSopenharmony_ci              " (USNO " + df_t->format(expset,s3) +
3412e5b6d6dSopenharmony_ci              " d=" + deltaset + "s)");
3422e5b6d6dSopenharmony_ci      } else {
3432e5b6d6dSopenharmony_ci        logln(df_d->format(cal.getTime(status),s1) +
3442e5b6d6dSopenharmony_ci              ", Sunset: " + df_dt->format(sunset,s2) +
3452e5b6d6dSopenharmony_ci              " (USNO " + df_t->format(expset,s3) + ")");
3462e5b6d6dSopenharmony_ci      }
3472e5b6d6dSopenharmony_ci    } else {
3482e5b6d6dSopenharmony_ci      logln(df_d->format(cal.getTime(status),s1) +
3492e5b6d6dSopenharmony_ci            ", Sunrise: " + df_dt->format(sunrise,s2) +
3502e5b6d6dSopenharmony_ci            " (USNO " + df_t->format(exprise,s3) + ")" +
3512e5b6d6dSopenharmony_ci            ", Sunset: " + df_dt->format(sunset,s4) +
3522e5b6d6dSopenharmony_ci            " (USNO " + df_t->format(expset,s5) + ")");
3532e5b6d6dSopenharmony_ci    }
3542e5b6d6dSopenharmony_ci    cal.add(UCAL_DATE, 1, status);
3552e5b6d6dSopenharmony_ci  }
3562e5b6d6dSopenharmony_ci
3572e5b6d6dSopenharmony_ci  //        CalendarAstronomer a = new CalendarAstronomer(-(71+5/60), 42+37/60);
3582e5b6d6dSopenharmony_ci  //        cal.clear();
3592e5b6d6dSopenharmony_ci  //        cal.set(cal.YEAR, 1986);
3602e5b6d6dSopenharmony_ci  //        cal.set(cal.MONTH, cal.MARCH);
3612e5b6d6dSopenharmony_ci  //        cal.set(cal.DATE, 10);
3622e5b6d6dSopenharmony_ci  //        cal.set(cal.YEAR, 1988);
3632e5b6d6dSopenharmony_ci  //        cal.set(cal.MONTH, cal.JULY);
3642e5b6d6dSopenharmony_ci  //        cal.set(cal.DATE, 27);
3652e5b6d6dSopenharmony_ci  //        a.setDate(cal.getTime());
3662e5b6d6dSopenharmony_ci  //        long r = a.getSunRiseSet2(true);
3672e5b6d6dSopenharmony_ci  closeAstro(status);
3682e5b6d6dSopenharmony_ci  ASSERT_OK(status);
3692e5b6d6dSopenharmony_ci}
3702e5b6d6dSopenharmony_ci
3712e5b6d6dSopenharmony_ci
3722e5b6d6dSopenharmony_ci
3732e5b6d6dSopenharmony_civoid AstroTest::TestBasics(void) {
3742e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
3752e5b6d6dSopenharmony_ci  initAstro(status);
3762e5b6d6dSopenharmony_ci  if (U_FAILURE(status)) {
3772e5b6d6dSopenharmony_ci    dataerrln("Got error: %s", u_errorName(status));
3782e5b6d6dSopenharmony_ci    return;
3792e5b6d6dSopenharmony_ci  }
3802e5b6d6dSopenharmony_ci
3812e5b6d6dSopenharmony_ci  // Check that our JD computation is the same as the book's (p. 88)
3822e5b6d6dSopenharmony_ci  GregorianCalendar cal3(TimeZone::getGMT()->clone(), Locale::getUS(), status);
3832e5b6d6dSopenharmony_ci  LocalPointer<DateFormat> d3(DateFormat::createDateTimeInstance(DateFormat::MEDIUM,DateFormat::MEDIUM,Locale::getUS()));
3842e5b6d6dSopenharmony_ci  if (d3.isNull()) {
3852e5b6d6dSopenharmony_ci      dataerrln("Got error: %s", u_errorName(status));
3862e5b6d6dSopenharmony_ci      closeAstro(status);
3872e5b6d6dSopenharmony_ci      return;
3882e5b6d6dSopenharmony_ci  }
3892e5b6d6dSopenharmony_ci  d3->setTimeZone(*TimeZone::getGMT());
3902e5b6d6dSopenharmony_ci  cal3.clear();
3912e5b6d6dSopenharmony_ci  cal3.set(UCAL_YEAR, 1980);
3922e5b6d6dSopenharmony_ci  cal3.set(UCAL_MONTH, UCAL_JULY);
3932e5b6d6dSopenharmony_ci  cal3.set(UCAL_DATE, 2);
3942e5b6d6dSopenharmony_ci  logln("cal3[a]=%.1lf, d=%d\n", cal3.getTime(status), cal3.get(UCAL_JULIAN_DAY,status));
3952e5b6d6dSopenharmony_ci  {
3962e5b6d6dSopenharmony_ci    UnicodeString s;
3972e5b6d6dSopenharmony_ci    logln(UnicodeString("cal3[a] = ") + d3->format(cal3.getTime(status),s));
3982e5b6d6dSopenharmony_ci  }
3992e5b6d6dSopenharmony_ci  cal3.clear();
4002e5b6d6dSopenharmony_ci  cal3.set(UCAL_YEAR, 1980);
4012e5b6d6dSopenharmony_ci  cal3.set(UCAL_MONTH, UCAL_JULY);
4022e5b6d6dSopenharmony_ci  cal3.set(UCAL_DATE, 27);
4032e5b6d6dSopenharmony_ci  logln("cal3=%.1lf, d=%d\n", cal3.getTime(status), cal3.get(UCAL_JULIAN_DAY,status));
4042e5b6d6dSopenharmony_ci
4052e5b6d6dSopenharmony_ci  ASSERT_OK(status);
4062e5b6d6dSopenharmony_ci  {
4072e5b6d6dSopenharmony_ci    UnicodeString s;
4082e5b6d6dSopenharmony_ci    logln(UnicodeString("cal3 = ") + d3->format(cal3.getTime(status),s));
4092e5b6d6dSopenharmony_ci  }
4102e5b6d6dSopenharmony_ci  astro->setTime(cal3.getTime(status));
4112e5b6d6dSopenharmony_ci  double jd = astro->getJulianDay() - 2447891.5;
4122e5b6d6dSopenharmony_ci  double exp = -3444.;
4132e5b6d6dSopenharmony_ci  if (jd == exp) {
4142e5b6d6dSopenharmony_ci    UnicodeString s;
4152e5b6d6dSopenharmony_ci    logln(d3->format(cal3.getTime(status),s) + " => " + jd);
4162e5b6d6dSopenharmony_ci  } else {
4172e5b6d6dSopenharmony_ci    UnicodeString s;
4182e5b6d6dSopenharmony_ci    errln("FAIL: " + d3->format(cal3.getTime(status), s) + " => " + jd +
4192e5b6d6dSopenharmony_ci          ", expected " + exp);
4202e5b6d6dSopenharmony_ci  }
4212e5b6d6dSopenharmony_ci
4222e5b6d6dSopenharmony_ci  //        cal3.clear();
4232e5b6d6dSopenharmony_ci  //        cal3.set(cal3.YEAR, 1990);
4242e5b6d6dSopenharmony_ci  //        cal3.set(cal3.MONTH, Calendar.JANUARY);
4252e5b6d6dSopenharmony_ci  //        cal3.set(cal3.DATE, 1);
4262e5b6d6dSopenharmony_ci  //        cal3.add(cal3.DATE, -1);
4272e5b6d6dSopenharmony_ci  //        astro.setDate(cal3.getTime());
4282e5b6d6dSopenharmony_ci  //        astro.foo();
4292e5b6d6dSopenharmony_ci
4302e5b6d6dSopenharmony_ci  ASSERT_OK(status);
4312e5b6d6dSopenharmony_ci  closeAstro(status);
4322e5b6d6dSopenharmony_ci  ASSERT_OK(status);
4332e5b6d6dSopenharmony_ci
4342e5b6d6dSopenharmony_ci}
4352e5b6d6dSopenharmony_ci
4362e5b6d6dSopenharmony_civoid AstroTest::TestMoonAge(void){
4372e5b6d6dSopenharmony_ci	UErrorCode status = U_ZERO_ERROR;
4382e5b6d6dSopenharmony_ci	initAstro(status);
4392e5b6d6dSopenharmony_ci	ASSERT_OK(status);
4402e5b6d6dSopenharmony_ci
4412e5b6d6dSopenharmony_ci	// more testcases are around the date 05/20/2012
4422e5b6d6dSopenharmony_ci	//ticket#3785  UDate ud0 = 1337557623000.0;
4432e5b6d6dSopenharmony_ci	static const double testcase[][10] = {{2012, 5, 20 , 16 , 48, 59},
4442e5b6d6dSopenharmony_ci	                {2012, 5, 20 , 16 , 47, 34},
4452e5b6d6dSopenharmony_ci	                {2012, 5, 21, 00, 00, 00},
4462e5b6d6dSopenharmony_ci	                {2012, 5, 20, 14, 55, 59},
4472e5b6d6dSopenharmony_ci	                {2012, 5, 21, 7, 40, 40},
4482e5b6d6dSopenharmony_ci	                {2023, 9, 25, 10,00, 00},
4492e5b6d6dSopenharmony_ci	                {2008, 7, 7, 15, 00, 33},
4502e5b6d6dSopenharmony_ci	                {1832, 9, 24, 2, 33, 41 },
4512e5b6d6dSopenharmony_ci	                {2016, 1, 31, 23, 59, 59},
4522e5b6d6dSopenharmony_ci	                {2099, 5, 20, 14, 55, 59}
4532e5b6d6dSopenharmony_ci	        };
4542e5b6d6dSopenharmony_ci	// Moon phase angle - Got from http://www.moonsystem.to/checkupe.htm
4552e5b6d6dSopenharmony_ci	static const double angle[] = {356.8493418421329, 356.8386760059673, 0.09625415252237701, 355.9986960782416, 3.5714026601303317, 124.26906744384183, 59.80247650195558,
4562e5b6d6dSopenharmony_ci									357.54163205513123, 268.41779281511094, 4.82340276581624};
4572e5b6d6dSopenharmony_ci	static const double precision = CalendarAstronomer::PI/32;
4582e5b6d6dSopenharmony_ci	for (int32_t i = 0; i < UPRV_LENGTHOF(testcase); i++) {
4592e5b6d6dSopenharmony_ci		gc->clear();
4602e5b6d6dSopenharmony_ci		logln((UnicodeString)"CASE["+i+"]: Year "+(int32_t)testcase[i][0]+" Month "+(int32_t)testcase[i][1]+" Day "+
4612e5b6d6dSopenharmony_ci		                                    (int32_t)testcase[i][2]+" Hour "+(int32_t)testcase[i][3]+" Minutes "+(int32_t)testcase[i][4]+
4622e5b6d6dSopenharmony_ci		                                    " Seconds "+(int32_t)testcase[i][5]);
4632e5b6d6dSopenharmony_ci		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]);
4642e5b6d6dSopenharmony_ci		astro->setDate(gc->getTime(status));
4652e5b6d6dSopenharmony_ci		double expectedAge = (angle[i]*CalendarAstronomer::PI)/180;
4662e5b6d6dSopenharmony_ci		double got = astro->getMoonAge();
4672e5b6d6dSopenharmony_ci		//logln(testString);
4682e5b6d6dSopenharmony_ci		if(!(got>expectedAge-precision && got<expectedAge+precision)){
4692e5b6d6dSopenharmony_ci			errln((UnicodeString)"FAIL: expected " + expectedAge +
4702e5b6d6dSopenharmony_ci					" got " + got);
4712e5b6d6dSopenharmony_ci		}else{
4722e5b6d6dSopenharmony_ci			logln((UnicodeString)"PASS: expected " + expectedAge +
4732e5b6d6dSopenharmony_ci					" got " + got);
4742e5b6d6dSopenharmony_ci		}
4752e5b6d6dSopenharmony_ci	}
4762e5b6d6dSopenharmony_ci	closeAstro(status);
4772e5b6d6dSopenharmony_ci	ASSERT_OK(status);
4782e5b6d6dSopenharmony_ci}
4792e5b6d6dSopenharmony_ci
4802e5b6d6dSopenharmony_ci
4812e5b6d6dSopenharmony_ci// TODO: try finding next new moon after  07/28/1984 16:00 GMT
4822e5b6d6dSopenharmony_ci
4832e5b6d6dSopenharmony_ci
4842e5b6d6dSopenharmony_ci#endif
4852e5b6d6dSopenharmony_ci
4862e5b6d6dSopenharmony_ci
4872e5b6d6dSopenharmony_ci
488