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