| /* |
| ******************************************************************************* |
| * Copyright (C) 1996-2008, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| package com.ibm.icu.dev.test.calendar; |
| |
| // AstroTest |
| |
| import java.util.Date; |
| import java.util.Locale; |
| |
| import com.ibm.icu.dev.test.*; |
| import com.ibm.icu.util.*; |
| import com.ibm.icu.impl.CalendarAstronomer; |
| import com.ibm.icu.impl.CalendarAstronomer.*; |
| import com.ibm.icu.text.DateFormat; |
| |
| // TODO: try finding next new moon after 07/28/1984 16:00 GMT |
| |
| public class AstroTest extends TestFmwk { |
| public static void main(String[] args) throws Exception { |
| new AstroTest().run(args); |
| } |
| |
| static final double PI = Math.PI; |
| |
| public void TestSolarLongitude() { |
| GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0, "UTC")); |
| CalendarAstronomer astro = new CalendarAstronomer(); |
| // year, month, day, hour, minute, longitude (radians), ascension(radians), declination(radians) |
| final double tests[][] = { |
| { 1980, 7, 27, 00, 00, 2.166442986535465, 2.2070499713207730, 0.3355704075759270 }, |
| { 1988, 7, 27, 00, 00, 2.167484927693959, 2.2081183335606176, 0.3353093444275315 }, |
| }; |
| logln(""); |
| for (int i = 0; i < tests.length; i++) { |
| gc.clear(); |
| gc.set((int)tests[i][0], (int)tests[i][1]-1, (int)tests[i][2], (int)tests[i][3], (int) tests[i][4]); |
| |
| astro.setDate(gc.getTime()); |
| |
| double longitude = astro.getSunLongitude(); |
| if (longitude != tests[i][5]) { |
| if ((float)longitude == (float)tests[i][5]) { |
| logln("longitude(" + longitude + |
| ") != tests[i][5](" + tests[i][5] + |
| ") in double for test " + i); |
| } else { |
| errln("FAIL: longitude(" + longitude + |
| ") != tests[i][5](" + tests[i][5] + |
| ") for test " + i); |
| } |
| } |
| Equatorial result = astro.getSunPosition(); |
| if (result.ascension != tests[i][6]) { |
| if ((float)result.ascension == (float)tests[i][6]) { |
| logln("result.ascension(" + result.ascension + |
| ") != tests[i][6](" + tests[i][6] + |
| ") in double for test " + i); |
| } else { |
| errln("FAIL: result.ascension(" + result.ascension + |
| ") != tests[i][6](" + tests[i][6] + |
| ") for test " + i); |
| } |
| } |
| if (result.declination != tests[i][7]) { |
| if ((float)result.declination == (float)tests[i][7]) { |
| logln("result.declination(" + result.declination + |
| ") != tests[i][7](" + tests[i][7] + |
| ") in double for test " + i); |
| } else { |
| errln("FAIL: result.declination(" + result.declination + |
| ") != tests[i][7](" + tests[i][7] + |
| ") for test " + i); |
| } |
| } |
| } |
| } |
| |
| public void TestLunarPosition() { |
| GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0, "UTC")); |
| CalendarAstronomer astro = new CalendarAstronomer(); |
| // year, month, day, hour, minute, ascension(radians), declination(radians) |
| final double tests[][] = { |
| { 1979, 2, 26, 16, 00, -0.3778379118188744, -0.1399698825594198 }, |
| }; |
| logln(""); |
| |
| for (int i = 0; i < tests.length; i++) { |
| gc.clear(); |
| gc.set((int)tests[i][0], (int)tests[i][1]-1, (int)tests[i][2], (int)tests[i][3], (int) tests[i][4]); |
| astro.setDate(gc.getTime()); |
| |
| Equatorial result = astro.getMoonPosition(); |
| if (result.ascension != tests[i][5]) { |
| if ((float)result.ascension == (float)tests[i][5]) { |
| logln("result.ascension(" + result.ascension + |
| ") != tests[i][5](" + tests[i][5] + |
| ") in double for test " + i); |
| } else { |
| errln("FAIL: result.ascension(" + result.ascension + |
| ") != tests[i][5](" + tests[i][5] + |
| ") for test " + i); |
| } |
| } |
| if (result.declination != tests[i][6]) { |
| if ((float)result.declination == (float)tests[i][6]) { |
| logln("result.declination(" + result.declination + |
| ") != tests[i][6](" + tests[i][6] + |
| ") in double for test " + i); |
| } else { |
| errln("FAIL: result.declination(" + result.declination + |
| ") != tests[i][6](" + tests[i][6] + |
| ") for test " + i); |
| } |
| } |
| } |
| } |
| |
| public void TestCoordinates() { |
| CalendarAstronomer astro = new CalendarAstronomer(); |
| Equatorial result = astro.eclipticToEquatorial(139.686111 * PI/ 180.0, 4.875278* PI / 180.0); |
| logln("result is " + result + "; " + result.toHmsString()); |
| } |
| |
| public void TestCoverage() { |
| GregorianCalendar cal = new GregorianCalendar(1958, Calendar.AUGUST, 15); |
| Date then = cal.getTime(); |
| CalendarAstronomer myastro = new CalendarAstronomer(then); |
| |
| //Latitude: 34 degrees 05' North |
| //Longitude: 118 degrees 22' West |
| double laLat = 34 + 5d/60, laLong = 360 - (118 + 22d/60); |
| CalendarAstronomer myastro2 = new CalendarAstronomer(laLong, laLat); |
| |
| double eclLat = laLat * Math.PI / 360; |
| double eclLong = laLong * Math.PI / 360; |
| Ecliptic ecl = new Ecliptic(eclLat, eclLong); |
| logln("ecliptic: " + ecl); |
| |
| CalendarAstronomer myastro3 = new CalendarAstronomer(); |
| myastro3.setJulianDay((4713 + 2000) * 365.25); |
| |
| CalendarAstronomer[] astronomers = { |
| myastro, myastro2, myastro3, myastro2 // check cache |
| |
| }; |
| |
| for (int i = 0; i < astronomers.length; ++i) { |
| CalendarAstronomer astro = astronomers[i]; |
| |
| logln("astro: " + astro); |
| logln(" time: " + astro.getTime()); |
| logln(" date: " + astro.getDate()); |
| logln(" cent: " + astro.getJulianCentury()); |
| logln(" gw sidereal: " + astro.getGreenwichSidereal()); |
| logln(" loc sidereal: " + astro.getLocalSidereal()); |
| logln(" equ ecl: " + astro.eclipticToEquatorial(ecl)); |
| logln(" equ long: " + astro.eclipticToEquatorial(eclLong)); |
| logln(" horiz: " + astro.eclipticToHorizon(eclLong)); |
| logln(" sunrise: " + new Date(astro.getSunRiseSet(true))); |
| logln(" sunset: " + new Date(astro.getSunRiseSet(false))); |
| logln(" moon phase: " + astro.getMoonPhase()); |
| logln(" moonrise: " + new Date(astro.getMoonRiseSet(true))); |
| logln(" moonset: " + new Date(astro.getMoonRiseSet(false))); |
| logln(" prev summer solstice: " + new Date(astro.getSunTime(CalendarAstronomer.SUMMER_SOLSTICE, false))); |
| logln(" next summer solstice: " + new Date(astro.getSunTime(CalendarAstronomer.SUMMER_SOLSTICE, true))); |
| logln(" prev full moon: " + new Date(astro.getMoonTime(CalendarAstronomer.FULL_MOON, false))); |
| logln(" next full moon: " + new Date(astro.getMoonTime(CalendarAstronomer.FULL_MOON, true))); |
| } |
| |
| } |
| |
| static final long DAY_MS = 24*60*60*1000L; |
| |
| public void TestSunriseTimes() { |
| |
| // logln("Sunrise/Sunset times for San Jose, California, USA"); |
| // CalendarAstronomer astro = new CalendarAstronomer(-121.55, 37.20); |
| // TimeZone tz = TimeZone.getTimeZone("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 |
| int[] 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"); |
| CalendarAstronomer astro = 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, Locale.US); |
| GregorianCalendar cal2 = new GregorianCalendar(tz, Locale.US); |
| cal.clear(); |
| cal.set(Calendar.YEAR, 2001); |
| cal.set(Calendar.MONTH, Calendar.APRIL); |
| cal.set(Calendar.DAY_OF_MONTH, 1); |
| cal.set(Calendar.HOUR_OF_DAY, 12); // must be near local noon for getSunRiseSet to work |
| |
| DateFormat df = DateFormat.getTimeInstance(cal, DateFormat.MEDIUM, Locale.US); |
| DateFormat df2 = DateFormat.getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US); |
| DateFormat day = DateFormat.getDateInstance(cal, DateFormat.MEDIUM, Locale.US); |
| |
| for (int i=0; i < 30; i++) { |
| astro.setDate(cal.getTime()); |
| |
| Date sunrise = new Date(astro.getSunRiseSet(true)); |
| Date sunset = new Date(astro.getSunRiseSet(false)); |
| |
| cal2.setTime(cal.getTime()); |
| cal2.set(Calendar.SECOND, 0); |
| cal2.set(Calendar.MILLISECOND, 0); |
| |
| cal2.set(Calendar.HOUR_OF_DAY, USNO[4*i+0]); |
| cal2.set(Calendar.MINUTE, USNO[4*i+1]); |
| Date exprise = cal2.getTime(); |
| cal2.set(Calendar.HOUR_OF_DAY, USNO[4*i+2]); |
| cal2.set(Calendar.MINUTE, USNO[4*i+3]); |
| Date expset = cal2.getTime(); |
| // Compute delta of what we got to the USNO data, in seconds |
| int deltarise = Math.abs((int)(sunrise.getTime() - exprise.getTime()) / 1000); |
| int deltaset = Math.abs((int)(sunset.getTime() - expset.getTime()) / 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. |
| final int MAX_DEV = 180; |
| if (deltarise > MAX_DEV || deltaset > MAX_DEV) { |
| if (deltarise > MAX_DEV) { |
| errln("FAIL: " + day.format(cal.getTime()) + |
| ", Sunrise: " + df2.format(sunrise) + |
| " (USNO " + df.format(exprise) + |
| " d=" + deltarise + "s)"); |
| } else { |
| logln(day.format(cal.getTime()) + |
| ", Sunrise: " + df.format(sunrise) + |
| " (USNO " + df.format(exprise) + ")"); |
| } |
| if (deltaset > MAX_DEV) { |
| errln("FAIL: " + day.format(cal.getTime()) + |
| ", Sunset: " + df2.format(sunset) + |
| " (USNO " + df.format(expset) + |
| " d=" + deltaset + "s)"); |
| } else { |
| logln(day.format(cal.getTime()) + |
| ", Sunset: " + df.format(sunset) + |
| " (USNO " + df.format(expset) + ")"); |
| } |
| } else { |
| logln(day.format(cal.getTime()) + |
| ", Sunrise: " + df.format(sunrise) + |
| " (USNO " + df.format(exprise) + ")" + |
| ", Sunset: " + df.format(sunset) + |
| " (USNO " + df.format(expset) + ")"); |
| } |
| cal.add(Calendar.DATE, 1); |
| } |
| |
| // 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); |
| } |
| |
| public void TestBasics() { |
| // Check that our JD computation is the same as the book's (p. 88) |
| CalendarAstronomer astro = new CalendarAstronomer(); |
| GregorianCalendar cal3 = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US); |
| DateFormat d3 = DateFormat.getDateTimeInstance(cal3, DateFormat.MEDIUM,DateFormat.MEDIUM,Locale.US); |
| cal3.clear(); |
| cal3.set(Calendar.YEAR, 1980); |
| cal3.set(Calendar.MONTH, Calendar.JULY); |
| cal3.set(Calendar.DATE, 27); |
| astro.setDate(cal3.getTime()); |
| double jd = astro.getJulianDay() - 2447891.5; |
| double exp = -3444; |
| if (jd == exp) { |
| logln(d3.format(cal3.getTime()) + " => " + jd); |
| } else { |
| errln("FAIL: " + d3.format(cal3.getTime()) + " => " + 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(); |
| } |
| |
| public void TestMoonAge(){ |
| GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0,"GMT")); |
| CalendarAstronomer calastro = new CalendarAstronomer(); |
| // more testcases are around the date 05/20/2012 |
| //ticket#3785 UDate ud0 = 1337557623000.0; |
| double testcase[][] = {{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 |
| double angle[] = {356.8493418421329, 356.8386760059673, 0.09625415252237701, 355.9986960782416, 3.5714026601303317, 124.26906744384183, 59.80247650195558, 357.54163205513123, 268.41779281511094, 4.82340276581624}; |
| double precision = PI/32; |
| for(int i=0; i<testcase.length; i++){ |
| gc.clear(); |
| String testString = "CASE["+i+"]: Year "+(int)testcase[i][0]+" Month "+(int)testcase[i][1]+" Day "+ |
| (int)testcase[i][2]+" Hour "+(int)testcase[i][3]+" Minutes "+(int)testcase[i][4]+ |
| " Seconds "+(int)testcase[i][5]; |
| 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]); |
| calastro.setDate(gc.getTime()); |
| double expectedAge = (angle[i]*PI)/180; |
| double got = calastro.getMoonAge(); |
| logln(testString); |
| if(!(got>expectedAge-precision && got<expectedAge+precision)){ |
| errln("FAIL: expected " + expectedAge + |
| " got " + got); |
| }else{ |
| logln("PASS: expected " + expectedAge + |
| " got " + got); |
| } |
| } |
| } |
| } |