Home | History | Annotate | Download | only in calendar
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5  *******************************************************************************
      6  * Copyright (C) 1996-2010, International Business Machines Corporation and    *
      7  * others. All Rights Reserved.                                                *
      8  *******************************************************************************
      9  */
     10 package android.icu.dev.test.calendar;
     11 
     12 // AstroTest
     13 
     14 import java.util.Date;
     15 import java.util.Locale;
     16 
     17 import org.junit.Test;
     18 
     19 import android.icu.dev.test.TestFmwk;
     20 import android.icu.impl.CalendarAstronomer;
     21 import android.icu.impl.CalendarAstronomer.Ecliptic;
     22 import android.icu.impl.CalendarAstronomer.Equatorial;
     23 import android.icu.text.DateFormat;
     24 import android.icu.util.Calendar;
     25 import android.icu.util.GregorianCalendar;
     26 import android.icu.util.SimpleTimeZone;
     27 import android.icu.util.TimeZone;
     28 
     29 // TODO: try finding next new moon after  07/28/1984 16:00 GMT
     30 
     31 public class AstroTest extends TestFmwk {
     32     static final double PI = Math.PI;
     33 
     34     @Test
     35     public void TestSolarLongitude() {
     36         GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0, "UTC"));
     37         CalendarAstronomer astro = new CalendarAstronomer();
     38         // year, month, day, hour, minute, longitude (radians), ascension(radians), declination(radians)
     39         final double tests[][] = {
     40             { 1980, 7, 27, 00, 00, 2.166442986535465, 2.2070499713207730, 0.3355704075759270 },
     41             { 1988, 7, 27, 00, 00, 2.167484927693959, 2.2081183335606176, 0.3353093444275315 },
     42         };
     43         logln("");
     44         for (int i = 0; i < tests.length; i++) {
     45             gc.clear();
     46             gc.set((int)tests[i][0], (int)tests[i][1]-1, (int)tests[i][2], (int)tests[i][3], (int) tests[i][4]);
     47 
     48             astro.setDate(gc.getTime());
     49 
     50             double longitude = astro.getSunLongitude();
     51             if (longitude != tests[i][5]) {
     52                 if ((float)longitude == (float)tests[i][5]) {
     53                     logln("longitude(" + longitude +
     54                             ") !=  tests[i][5](" + tests[i][5] +
     55                             ") in double for test " + i);
     56                 } else {
     57                     errln("FAIL: longitude(" + longitude +
     58                             ") !=  tests[i][5](" + tests[i][5] +
     59                             ") for test " + i);
     60                 }
     61             }
     62             Equatorial result = astro.getSunPosition();
     63             if (result.ascension != tests[i][6]) {
     64                 if ((float)result.ascension == (float)tests[i][6]) {
     65                     logln("result.ascension(" + result.ascension +
     66                             ") !=  tests[i][6](" + tests[i][6] +
     67                             ") in double for test " + i);
     68                 } else {
     69                     errln("FAIL: result.ascension(" + result.ascension +
     70                             ") !=  tests[i][6](" + tests[i][6] +
     71                             ") for test " + i);
     72                 }
     73             }
     74             if (result.declination != tests[i][7]) {
     75                 if ((float)result.declination == (float)tests[i][7]) {
     76                     logln("result.declination(" + result.declination +
     77                             ") !=  tests[i][7](" + tests[i][7] +
     78                             ") in double for test " + i);
     79                 } else {
     80                     errln("FAIL: result.declination(" + result.declination +
     81                             ") !=  tests[i][7](" + tests[i][7] +
     82                             ") for test " + i);
     83                 }
     84             }
     85         }
     86     }
     87 
     88     @Test
     89     public void TestLunarPosition() {
     90         GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0, "UTC"));
     91         CalendarAstronomer astro = new CalendarAstronomer();
     92         // year, month, day, hour, minute, ascension(radians), declination(radians)
     93         final double tests[][] = {
     94             { 1979, 2, 26, 16, 00, -0.3778379118188744, -0.1399698825594198 },
     95         };
     96         logln("");
     97 
     98         for (int i = 0; i < tests.length; i++) {
     99             gc.clear();
    100             gc.set((int)tests[i][0], (int)tests[i][1]-1, (int)tests[i][2], (int)tests[i][3], (int) tests[i][4]);
    101             astro.setDate(gc.getTime());
    102 
    103             Equatorial result = astro.getMoonPosition();
    104             if (result.ascension != tests[i][5]) {
    105                 if ((float)result.ascension == (float)tests[i][5]) {
    106                     logln("result.ascension(" + result.ascension +
    107                             ") !=  tests[i][5](" + tests[i][5] +
    108                             ") in double for test " + i);
    109                 } else {
    110                     errln("FAIL: result.ascension(" + result.ascension +
    111                             ") !=  tests[i][5](" + tests[i][5] +
    112                             ") for test " + i);
    113                 }
    114             }
    115             if (result.declination != tests[i][6]) {
    116                 if ((float)result.declination == (float)tests[i][6]) {
    117                     logln("result.declination(" + result.declination +
    118                             ") !=  tests[i][6](" + tests[i][6] +
    119                             ") in double for test " + i);
    120                 } else {
    121                     errln("FAIL: result.declination(" + result.declination +
    122                             ") !=  tests[i][6](" + tests[i][6] +
    123                             ") for test " + i);
    124                 }
    125             }
    126         }
    127     }
    128 
    129     @Test
    130     public void TestCoordinates() {
    131         CalendarAstronomer astro = new CalendarAstronomer();
    132         Equatorial result = astro.eclipticToEquatorial(139.686111 * PI/ 180.0, 4.875278* PI / 180.0);
    133         logln("result is " + result + ";  " + result.toHmsString());
    134     }
    135 
    136     @Test
    137     public void TestCoverage() {
    138         GregorianCalendar cal = new GregorianCalendar(1958, Calendar.AUGUST, 15);
    139         Date then = cal.getTime();
    140         CalendarAstronomer myastro = new CalendarAstronomer(then);
    141 
    142         //Latitude:  34 degrees 05' North
    143         //Longitude:  118 degrees 22' West
    144         double laLat = 34 + 5d/60, laLong = 360 - (118 + 22d/60);
    145         CalendarAstronomer myastro2 = new CalendarAstronomer(laLong, laLat);
    146 
    147         double eclLat = laLat * Math.PI / 360;
    148         double eclLong = laLong * Math.PI / 360;
    149         Ecliptic ecl = new Ecliptic(eclLat, eclLong);
    150         logln("ecliptic: " + ecl);
    151 
    152         CalendarAstronomer myastro3 = new CalendarAstronomer();
    153         myastro3.setJulianDay((4713 + 2000) * 365.25);
    154 
    155         CalendarAstronomer[] astronomers = {
    156             myastro, myastro2, myastro3, myastro2 // check cache
    157 
    158         };
    159 
    160         for (int i = 0; i < astronomers.length; ++i) {
    161             CalendarAstronomer astro = astronomers[i];
    162 
    163             logln("astro: " + astro);
    164             logln("   time: " + astro.getTime());
    165             logln("   date: " + astro.getDate());
    166             logln("   cent: " + astro.getJulianCentury());
    167             logln("   gw sidereal: " + astro.getGreenwichSidereal());
    168             logln("   loc sidereal: " + astro.getLocalSidereal());
    169             logln("   equ ecl: " + astro.eclipticToEquatorial(ecl));
    170             logln("   equ long: " + astro.eclipticToEquatorial(eclLong));
    171             logln("   horiz: " + astro.eclipticToHorizon(eclLong));
    172             logln("   sunrise: " + new Date(astro.getSunRiseSet(true)));
    173             logln("   sunset: " + new Date(astro.getSunRiseSet(false)));
    174             logln("   moon phase: " + astro.getMoonPhase());
    175             logln("   moonrise: " + new Date(astro.getMoonRiseSet(true)));
    176             logln("   moonset: " + new Date(astro.getMoonRiseSet(false)));
    177             logln("   prev summer solstice: " + new Date(astro.getSunTime(CalendarAstronomer.SUMMER_SOLSTICE, false)));
    178             logln("   next summer solstice: " + new Date(astro.getSunTime(CalendarAstronomer.SUMMER_SOLSTICE, true)));
    179             logln("   prev full moon: " + new Date(astro.getMoonTime(CalendarAstronomer.FULL_MOON, false)));
    180             logln("   next full moon: " + new Date(astro.getMoonTime(CalendarAstronomer.FULL_MOON, true)));
    181         }
    182 
    183     }
    184 
    185     static final long DAY_MS = 24*60*60*1000L;
    186 
    187     @Test
    188     public void TestSunriseTimes() {
    189 
    190         //        logln("Sunrise/Sunset times for San Jose, California, USA");
    191         //        CalendarAstronomer astro = new CalendarAstronomer(-121.55, 37.20);
    192         //        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
    193 
    194         // We'll use a table generated by the UNSO website as our reference
    195         // From: http://aa.usno.navy.mil/
    196         //-Location: W079 25, N43 40
    197         //-Rise and Set for the Sun for 2001
    198         //-Zone:  4h West of Greenwich
    199         int[] USNO = {
    200              6,59, 19,45,
    201              6,57, 19,46,
    202              6,56, 19,47,
    203              6,54, 19,48,
    204              6,52, 19,49,
    205              6,50, 19,51,
    206              6,48, 19,52,
    207              6,47, 19,53,
    208              6,45, 19,54,
    209              6,43, 19,55,
    210              6,42, 19,57,
    211              6,40, 19,58,
    212              6,38, 19,59,
    213              6,36, 20, 0,
    214              6,35, 20, 1,
    215              6,33, 20, 3,
    216              6,31, 20, 4,
    217              6,30, 20, 5,
    218              6,28, 20, 6,
    219              6,27, 20, 7,
    220              6,25, 20, 8,
    221              6,23, 20,10,
    222              6,22, 20,11,
    223              6,20, 20,12,
    224              6,19, 20,13,
    225              6,17, 20,14,
    226              6,16, 20,16,
    227              6,14, 20,17,
    228              6,13, 20,18,
    229              6,11, 20,19,
    230         };
    231 
    232         logln("Sunrise/Sunset times for Toronto, Canada");
    233         CalendarAstronomer astro = new CalendarAstronomer(-(79+25/60), 43+40/60);
    234 
    235         // As of ICU4J 2.8 the ICU4J time zones implement pass-through
    236         // to the underlying JDK.  Because of variation in the
    237         // underlying JDKs, we have to use a fixed-offset
    238         // SimpleTimeZone to get consistent behavior between JDKs.
    239         // The offset we want is [-18000000, 3600000] (raw, dst).
    240         // [aliu 10/15/03]
    241 
    242         // TimeZone tz = TimeZone.getTimeZone("America/Montreal");
    243         TimeZone tz = new SimpleTimeZone(-18000000 + 3600000, "Montreal(FIXED)");
    244 
    245         GregorianCalendar cal = new GregorianCalendar(tz, Locale.US);
    246         GregorianCalendar cal2 = new GregorianCalendar(tz, Locale.US);
    247         cal.clear();
    248         cal.set(Calendar.YEAR, 2001);
    249         cal.set(Calendar.MONTH, Calendar.APRIL);
    250         cal.set(Calendar.DAY_OF_MONTH, 1);
    251         cal.set(Calendar.HOUR_OF_DAY, 12); // must be near local noon for getSunRiseSet to work
    252 
    253         DateFormat df = DateFormat.getTimeInstance(cal, DateFormat.MEDIUM, Locale.US);
    254         DateFormat df2 = DateFormat.getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US);
    255         DateFormat day = DateFormat.getDateInstance(cal, DateFormat.MEDIUM, Locale.US);
    256 
    257         for (int i=0; i < 30; i++) {
    258             astro.setDate(cal.getTime());
    259 
    260             Date sunrise = new Date(astro.getSunRiseSet(true));
    261             Date sunset = new Date(astro.getSunRiseSet(false));
    262 
    263             cal2.setTime(cal.getTime());
    264             cal2.set(Calendar.SECOND,      0);
    265             cal2.set(Calendar.MILLISECOND, 0);
    266 
    267             cal2.set(Calendar.HOUR_OF_DAY, USNO[4*i+0]);
    268             cal2.set(Calendar.MINUTE,      USNO[4*i+1]);
    269             Date exprise = cal2.getTime();
    270             cal2.set(Calendar.HOUR_OF_DAY, USNO[4*i+2]);
    271             cal2.set(Calendar.MINUTE,      USNO[4*i+3]);
    272             Date expset = cal2.getTime();
    273             // Compute delta of what we got to the USNO data, in seconds
    274             int deltarise = Math.abs((int)(sunrise.getTime() - exprise.getTime()) / 1000);
    275             int deltaset = Math.abs((int)(sunset.getTime() - expset.getTime()) / 1000);
    276 
    277             // Allow a deviation of 0..MAX_DEV seconds
    278             // It would be nice to get down to 60 seconds, but at this
    279             // point that appears to be impossible without a redo of the
    280             // algorithm using something more advanced than Duffett-Smith.
    281             final int MAX_DEV = 180;
    282             if (deltarise > MAX_DEV || deltaset > MAX_DEV) {
    283                 if (deltarise > MAX_DEV) {
    284                     errln("FAIL: " + day.format(cal.getTime()) +
    285                           ", Sunrise: " + df2.format(sunrise) +
    286                           " (USNO " + df.format(exprise) +
    287                           " d=" + deltarise + "s)");
    288                 } else {
    289                     logln(day.format(cal.getTime()) +
    290                           ", Sunrise: " + df.format(sunrise) +
    291                           " (USNO " + df.format(exprise) + ")");
    292                 }
    293                 if (deltaset > MAX_DEV) {
    294                     errln("FAIL: " + day.format(cal.getTime()) +
    295                           ", Sunset: " + df2.format(sunset) +
    296                           " (USNO " + df.format(expset) +
    297                           " d=" + deltaset + "s)");
    298                 } else {
    299                     logln(day.format(cal.getTime()) +
    300                           ", Sunset: " + df.format(sunset) +
    301                           " (USNO " + df.format(expset) + ")");
    302                 }
    303             } else {
    304                 logln(day.format(cal.getTime()) +
    305                       ", Sunrise: " + df.format(sunrise) +
    306                       " (USNO " + df.format(exprise) + ")" +
    307                       ", Sunset: " + df.format(sunset) +
    308                       " (USNO " + df.format(expset) + ")");
    309             }
    310             cal.add(Calendar.DATE, 1);
    311         }
    312 
    313 //        CalendarAstronomer a = new CalendarAstronomer(-(71+5/60), 42+37/60);
    314 //        cal.clear();
    315 //        cal.set(cal.YEAR, 1986);
    316 //        cal.set(cal.MONTH, cal.MARCH);
    317 //        cal.set(cal.DATE, 10);
    318 //        cal.set(cal.YEAR, 1988);
    319 //        cal.set(cal.MONTH, cal.JULY);
    320 //        cal.set(cal.DATE, 27);
    321 //        a.setDate(cal.getTime());
    322 //        long r = a.getSunRiseSet2(true);
    323     }
    324 
    325     @Test
    326     public void TestBasics() {
    327         // Check that our JD computation is the same as the book's (p. 88)
    328         CalendarAstronomer astro = new CalendarAstronomer();
    329         GregorianCalendar cal3 = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US);
    330         DateFormat d3 = DateFormat.getDateTimeInstance(cal3, DateFormat.MEDIUM,DateFormat.MEDIUM,Locale.US);
    331         cal3.clear();
    332         cal3.set(Calendar.YEAR, 1980);
    333         cal3.set(Calendar.MONTH, Calendar.JULY);
    334         cal3.set(Calendar.DATE, 27);
    335         astro.setDate(cal3.getTime());
    336         double jd = astro.getJulianDay() - 2447891.5;
    337         double exp = -3444;
    338         if (jd == exp) {
    339             logln(d3.format(cal3.getTime()) + " => " + jd);
    340         } else {
    341             errln("FAIL: " + d3.format(cal3.getTime()) + " => " + jd +
    342                   ", expected " + exp);
    343         }
    344 
    345 
    346 //        cal3.clear();
    347 //        cal3.set(cal3.YEAR, 1990);
    348 //        cal3.set(cal3.MONTH, Calendar.JANUARY);
    349 //        cal3.set(cal3.DATE, 1);
    350 //        cal3.add(cal3.DATE, -1);
    351 //        astro.setDate(cal3.getTime());
    352 //        astro.foo();
    353     }
    354 
    355     @Test
    356     public void TestMoonAge(){
    357         GregorianCalendar gc = new GregorianCalendar(new SimpleTimeZone(0,"GMT"));
    358         CalendarAstronomer calastro = new CalendarAstronomer();
    359         // more testcases are around the date 05/20/2012
    360         //ticket#3785  UDate ud0 = 1337557623000.0;
    361         double testcase[][] = {{2012, 5, 20 , 16 , 48, 59},
    362                 {2012, 5, 20 , 16 , 47, 34},
    363                 {2012, 5, 21, 00, 00, 00},
    364                 {2012, 5, 20, 14, 55, 59},
    365                 {2012, 5, 21, 7, 40, 40},
    366                 {2023, 9, 25, 10,00, 00},
    367                 {2008, 7, 7, 15, 00, 33},
    368                 {1832, 9, 24, 2, 33, 41 },
    369                 {2016, 1, 31, 23, 59, 59},
    370                 {2099, 5, 20, 14, 55, 59}
    371         };
    372         // Moon phase angle - Got from http://www.moonsystem.to/checkupe.htm
    373         double angle[] = {356.8493418421329, 356.8386760059673, 0.09625415252237701, 355.9986960782416, 3.5714026601303317, 124.26906744384183, 59.80247650195558, 357.54163205513123, 268.41779281511094, 4.82340276581624};
    374         double precision = PI/32;
    375         for(int i=0; i<testcase.length; i++){
    376             gc.clear();
    377             String testString = "CASE["+i+"]: Year "+(int)testcase[i][0]+" Month "+(int)testcase[i][1]+" Day "+
    378                                     (int)testcase[i][2]+" Hour "+(int)testcase[i][3]+" Minutes "+(int)testcase[i][4]+
    379                                     " Seconds "+(int)testcase[i][5];
    380             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]);
    381             calastro.setDate(gc.getTime());
    382             double expectedAge = (angle[i]*PI)/180;
    383             double got = calastro.getMoonAge();
    384             logln(testString);
    385             if(!(got>expectedAge-precision && got<expectedAge+precision)){
    386                 errln("FAIL: expected " + expectedAge +
    387                         " got " + got);
    388             }else{
    389                 logln("PASS: expected " + expectedAge +
    390                         " got " + got);
    391             }
    392         }
    393     }
    394 }
    395