diff options
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/test/intltest/astrotst.cpp')
-rw-r--r-- | Build/source/libs/icu/icu-xetex/test/intltest/astrotst.cpp | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/test/intltest/astrotst.cpp b/Build/source/libs/icu/icu-xetex/test/intltest/astrotst.cpp new file mode 100644 index 00000000000..ba7b5711396 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/test/intltest/astrotst.cpp @@ -0,0 +1,436 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 1996-2006, 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 "gregoimp.h" // for Math +#include "unicode/simpletz.h" + + +static const double DAY_MS = 24.*60.*60.*1000.; + +#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); + default: name = ""; break; + } +} + +#undef CASE + +#define ASSERT_OK(x) if(U_FAILURE(x)) { errln("%s:%d: %s\n", __FILE__, __LINE__, u_errorName(x)); return; } + + +void AstroTest::initAstro(UErrorCode &status) { + if(U_FAILURE(status)) return; + + if((astro != NULL) || (gc != NULL)) { + errln("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 < sizeof(tests)/sizeof(tests[0]); 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 < (int32_t)(sizeof(tests)/sizeof(tests[0])); 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 < sizeof(astronomers)/sizeof(astronomers[0]); ++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 = new CalendarAstronomer(-(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"); + TimeZone *tz = new SimpleTimeZone(-18000000 + 3600000, "Montreal(FIXED)"); + + GregorianCalendar *cal = new GregorianCalendar(tz->clone(), Locale::getUS(), status); + GregorianCalendar *cal2 = new GregorianCalendar(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 + + DateFormat *df_t = DateFormat::createTimeInstance(DateFormat::MEDIUM,Locale::getUS()); + DateFormat *df_d = DateFormat::createDateInstance(DateFormat::MEDIUM,Locale::getUS()); + DateFormat *df_dt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::MEDIUM, Locale::getUS()); + if(!df_t || !df_d || !df_dt) { + errln("couldn't create dateformats."); + 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); + delete astro3; + delete tz; + delete cal; + delete cal2; + delete df_t; + delete df_d; + delete df_dt; + closeAstro(status); + ASSERT_OK(status); +} + + + +void AstroTest::TestBasics(void) { + UErrorCode status = U_ZERO_ERROR; + initAstro(status); + ASSERT_OK(status); + + // Check that our JD computation is the same as the book's (p. 88) + GregorianCalendar *cal3 = new GregorianCalendar(TimeZone::getGMT()->clone(), Locale::getUS(), status); + DateFormat *d3 = DateFormat::createDateTimeInstance(DateFormat::MEDIUM,DateFormat::MEDIUM,Locale::getUS()); + 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(); + + delete cal3; + delete d3; + ASSERT_OK(status); + closeAstro(status); + ASSERT_OK(status); + +} + + +// TODO: try finding next new moon after 07/28/1984 16:00 GMT + + +#endif + + + |