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