Line data Source code
1 : // © 2016 and later: Unicode, Inc. and others.
2 : // License & terms of use: http://www.unicode.org/copyright.html
3 : /************************************************************************
4 : * Copyright (C) 1996-2008, International Business Machines Corporation *
5 : * and others. All Rights Reserved. *
6 : ************************************************************************
7 : * 2003-nov-07 srl Port from Java
8 : */
9 :
10 : #ifndef ASTRO_H
11 : #define ASTRO_H
12 :
13 : #include "unicode/utypes.h"
14 :
15 : #if !UCONFIG_NO_FORMATTING
16 :
17 : #include "gregoimp.h" // for Math
18 : #include "unicode/unistr.h"
19 :
20 : U_NAMESPACE_BEGIN
21 :
22 : /**
23 : * <code>CalendarAstronomer</code> is a class that can perform the calculations to
24 : * determine the positions of the sun and moon, the time of sunrise and
25 : * sunset, and other astronomy-related data. The calculations it performs
26 : * are in some cases quite complicated, and this utility class saves you
27 : * the trouble of worrying about them.
28 : * <p>
29 : * The measurement of time is a very important part of astronomy. Because
30 : * astronomical bodies are constantly in motion, observations are only valid
31 : * at a given moment in time. Accordingly, each <code>CalendarAstronomer</code>
32 : * object has a <code>time</code> property that determines the date
33 : * and time for which its calculations are performed. You can set and
34 : * retrieve this property with {@link #setDate setDate}, {@link #getDate getDate}
35 : * and related methods.
36 : * <p>
37 : * Almost all of the calculations performed by this class, or by any
38 : * astronomer, are approximations to various degrees of accuracy. The
39 : * calculations in this class are mostly modelled after those described
40 : * in the book
41 : * <a href="http://www.amazon.com/exec/obidos/ISBN=0521356997" target="_top">
42 : * Practical Astronomy With Your Calculator</a>, by Peter J.
43 : * Duffett-Smith, Cambridge University Press, 1990. This is an excellent
44 : * book, and if you want a greater understanding of how these calculations
45 : * are performed it a very good, readable starting point.
46 : * <p>
47 : * <strong>WARNING:</strong> This class is very early in its development, and
48 : * it is highly likely that its API will change to some degree in the future.
49 : * At the moment, it basically does just enough to support {@link IslamicCalendar}
50 : * and {@link ChineseCalendar}.
51 : *
52 : * @author Laura Werner
53 : * @author Alan Liu
54 : * @internal
55 : */
56 : class U_I18N_API CalendarAstronomer : public UMemory {
57 : public:
58 : // some classes
59 :
60 : public:
61 : /**
62 : * Represents the position of an object in the sky relative to the ecliptic,
63 : * the plane of the earth's orbit around the Sun.
64 : * This is a spherical coordinate system in which the latitude
65 : * specifies the position north or south of the plane of the ecliptic.
66 : * The longitude specifies the position along the ecliptic plane
67 : * relative to the "First Point of Aries", which is the Sun's position in the sky
68 : * at the Vernal Equinox.
69 : * <p>
70 : * Note that Ecliptic objects are immutable and cannot be modified
71 : * once they are constructed. This allows them to be passed and returned by
72 : * value without worrying about whether other code will modify them.
73 : *
74 : * @see CalendarAstronomer.Equatorial
75 : * @see CalendarAstronomer.Horizon
76 : * @internal
77 : */
78 : class U_I18N_API Ecliptic : public UMemory {
79 : public:
80 : /**
81 : * Constructs an Ecliptic coordinate object.
82 : * <p>
83 : * @param lat The ecliptic latitude, measured in radians.
84 : * @param lon The ecliptic longitude, measured in radians.
85 : * @internal
86 : */
87 : Ecliptic(double lat = 0, double lon = 0) {
88 : latitude = lat;
89 : longitude = lon;
90 : }
91 :
92 : /**
93 : * Setter for Ecliptic Coordinate object
94 : * @param lat The ecliptic latitude, measured in radians.
95 : * @param lon The ecliptic longitude, measured in radians.
96 : * @internal
97 : */
98 : void set(double lat, double lon) {
99 : latitude = lat;
100 : longitude = lon;
101 : }
102 :
103 : /**
104 : * Return a string representation of this object
105 : * @internal
106 : */
107 : UnicodeString toString() const;
108 :
109 : /**
110 : * The ecliptic latitude, in radians. This specifies an object's
111 : * position north or south of the plane of the ecliptic,
112 : * with positive angles representing north.
113 : * @internal
114 : */
115 : double latitude;
116 :
117 : /**
118 : * The ecliptic longitude, in radians.
119 : * This specifies an object's position along the ecliptic plane
120 : * relative to the "First Point of Aries", which is the Sun's position
121 : * in the sky at the Vernal Equinox,
122 : * with positive angles representing east.
123 : * <p>
124 : * A bit of trivia: the first point of Aries is currently in the
125 : * constellation Pisces, due to the precession of the earth's axis.
126 : * @internal
127 : */
128 : double longitude;
129 : };
130 :
131 : /**
132 : * Represents the position of an
133 : * object in the sky relative to the plane of the earth's equator.
134 : * The <i>Right Ascension</i> specifies the position east or west
135 : * along the equator, relative to the sun's position at the vernal
136 : * equinox. The <i>Declination</i> is the position north or south
137 : * of the equatorial plane.
138 : * <p>
139 : * Note that Equatorial objects are immutable and cannot be modified
140 : * once they are constructed. This allows them to be passed and returned by
141 : * value without worrying about whether other code will modify them.
142 : *
143 : * @see CalendarAstronomer.Ecliptic
144 : * @see CalendarAstronomer.Horizon
145 : * @internal
146 : */
147 : class U_I18N_API Equatorial : public UMemory {
148 : public:
149 : /**
150 : * Constructs an Equatorial coordinate object.
151 : * <p>
152 : * @param asc The right ascension, measured in radians.
153 : * @param dec The declination, measured in radians.
154 : * @internal
155 : */
156 0 : Equatorial(double asc = 0, double dec = 0)
157 0 : : ascension(asc), declination(dec) { }
158 :
159 : /**
160 : * Setter
161 : * @param asc The right ascension, measured in radians.
162 : * @param dec The declination, measured in radians.
163 : * @internal
164 : */
165 0 : void set(double asc, double dec) {
166 0 : ascension = asc;
167 0 : declination = dec;
168 0 : }
169 :
170 : /**
171 : * Return a string representation of this object, with the
172 : * angles measured in degrees.
173 : * @internal
174 : */
175 : UnicodeString toString() const;
176 :
177 : /**
178 : * Return a string representation of this object with the right ascension
179 : * measured in hours, minutes, and seconds.
180 : * @internal
181 : */
182 : //String toHmsString() {
183 : //return radToHms(ascension) + "," + radToDms(declination);
184 : //}
185 :
186 : /**
187 : * The right ascension, in radians.
188 : * This is the position east or west along the equator
189 : * relative to the sun's position at the vernal equinox,
190 : * with positive angles representing East.
191 : * @internal
192 : */
193 : double ascension;
194 :
195 : /**
196 : * The declination, in radians.
197 : * This is the position north or south of the equatorial plane,
198 : * with positive angles representing north.
199 : * @internal
200 : */
201 : double declination;
202 : };
203 :
204 : /**
205 : * Represents the position of an object in the sky relative to
206 : * the local horizon.
207 : * The <i>Altitude</i> represents the object's elevation above the horizon,
208 : * with objects below the horizon having a negative altitude.
209 : * The <i>Azimuth</i> is the geographic direction of the object from the
210 : * observer's position, with 0 representing north. The azimuth increases
211 : * clockwise from north.
212 : * <p>
213 : * Note that Horizon objects are immutable and cannot be modified
214 : * once they are constructed. This allows them to be passed and returned by
215 : * value without worrying about whether other code will modify them.
216 : *
217 : * @see CalendarAstronomer.Ecliptic
218 : * @see CalendarAstronomer.Equatorial
219 : * @internal
220 : */
221 : class U_I18N_API Horizon : public UMemory {
222 : public:
223 : /**
224 : * Constructs a Horizon coordinate object.
225 : * <p>
226 : * @param alt The altitude, measured in radians above the horizon.
227 : * @param azim The azimuth, measured in radians clockwise from north.
228 : * @internal
229 : */
230 : Horizon(double alt=0, double azim=0)
231 : : altitude(alt), azimuth(azim) { }
232 :
233 : /**
234 : * Setter for Ecliptic Coordinate object
235 : * @param alt The altitude, measured in radians above the horizon.
236 : * @param azim The azimuth, measured in radians clockwise from north.
237 : * @internal
238 : */
239 0 : void set(double alt, double azim) {
240 0 : altitude = alt;
241 0 : azimuth = azim;
242 0 : }
243 :
244 : /**
245 : * Return a string representation of this object, with the
246 : * angles measured in degrees.
247 : * @internal
248 : */
249 : UnicodeString toString() const;
250 :
251 : /**
252 : * The object's altitude above the horizon, in radians.
253 : * @internal
254 : */
255 : double altitude;
256 :
257 : /**
258 : * The object's direction, in radians clockwise from north.
259 : * @internal
260 : */
261 : double azimuth;
262 : };
263 :
264 : public:
265 : //-------------------------------------------------------------------------
266 : // Assorted private data used for conversions
267 : //-------------------------------------------------------------------------
268 :
269 : // My own copies of these so compilers are more likely to optimize them away
270 : static const double PI;
271 :
272 : /**
273 : * The average number of solar days from one new moon to the next. This is the time
274 : * it takes for the moon to return the same ecliptic longitude as the sun.
275 : * It is longer than the sidereal month because the sun's longitude increases
276 : * during the year due to the revolution of the earth around the sun.
277 : * Approximately 29.53.
278 : *
279 : * @see #SIDEREAL_MONTH
280 : * @internal
281 : * @deprecated ICU 2.4. This class may be removed or modified.
282 : */
283 : static const double SYNODIC_MONTH;
284 :
285 : //-------------------------------------------------------------------------
286 : // Constructors
287 : //-------------------------------------------------------------------------
288 :
289 : /**
290 : * Construct a new <code>CalendarAstronomer</code> object that is initialized to
291 : * the current date and time.
292 : * @internal
293 : */
294 : CalendarAstronomer();
295 :
296 : /**
297 : * Construct a new <code>CalendarAstronomer</code> object that is initialized to
298 : * the specified date and time.
299 : * @internal
300 : */
301 : CalendarAstronomer(UDate d);
302 :
303 : /**
304 : * Construct a new <code>CalendarAstronomer</code> object with the given
305 : * latitude and longitude. The object's time is set to the current
306 : * date and time.
307 : * <p>
308 : * @param longitude The desired longitude, in <em>degrees</em> east of
309 : * the Greenwich meridian.
310 : *
311 : * @param latitude The desired latitude, in <em>degrees</em>. Positive
312 : * values signify North, negative South.
313 : *
314 : * @see java.util.Date#getTime()
315 : * @internal
316 : */
317 : CalendarAstronomer(double longitude, double latitude);
318 :
319 : /**
320 : * Destructor
321 : * @internal
322 : */
323 : ~CalendarAstronomer();
324 :
325 : //-------------------------------------------------------------------------
326 : // Time and date getters and setters
327 : //-------------------------------------------------------------------------
328 :
329 : /**
330 : * Set the current date and time of this <code>CalendarAstronomer</code> object. All
331 : * astronomical calculations are performed based on this time setting.
332 : *
333 : * @param aTime the date and time, expressed as the number of milliseconds since
334 : * 1/1/1970 0:00 GMT (Gregorian).
335 : *
336 : * @see #setDate
337 : * @see #getTime
338 : * @internal
339 : */
340 : void setTime(UDate aTime);
341 :
342 :
343 : /**
344 : * Set the current date and time of this <code>CalendarAstronomer</code> object. All
345 : * astronomical calculations are performed based on this time setting.
346 : *
347 : * @param aTime the date and time, expressed as the number of milliseconds since
348 : * 1/1/1970 0:00 GMT (Gregorian).
349 : *
350 : * @see #getTime
351 : * @internal
352 : */
353 : void setDate(UDate aDate) { setTime(aDate); }
354 :
355 : /**
356 : * Set the current date and time of this <code>CalendarAstronomer</code> object. All
357 : * astronomical calculations are performed based on this time setting.
358 : *
359 : * @param jdn the desired time, expressed as a "julian day number",
360 : * which is the number of elapsed days since
361 : * 1/1/4713 BC (Julian), 12:00 GMT. Note that julian day
362 : * numbers start at <em>noon</em>. To get the jdn for
363 : * the corresponding midnight, subtract 0.5.
364 : *
365 : * @see #getJulianDay
366 : * @see #JULIAN_EPOCH_MS
367 : * @internal
368 : */
369 : void setJulianDay(double jdn);
370 :
371 : /**
372 : * Get the current time of this <code>CalendarAstronomer</code> object,
373 : * represented as the number of milliseconds since
374 : * 1/1/1970 AD 0:00 GMT (Gregorian).
375 : *
376 : * @see #setTime
377 : * @see #getDate
378 : * @internal
379 : */
380 : UDate getTime();
381 :
382 : /**
383 : * Get the current time of this <code>CalendarAstronomer</code> object,
384 : * expressed as a "julian day number", which is the number of elapsed
385 : * days since 1/1/4713 BC (Julian), 12:00 GMT.
386 : *
387 : * @see #setJulianDay
388 : * @see #JULIAN_EPOCH_MS
389 : * @internal
390 : */
391 : double getJulianDay();
392 :
393 : /**
394 : * Return this object's time expressed in julian centuries:
395 : * the number of centuries after 1/1/1900 AD, 12:00 GMT
396 : *
397 : * @see #getJulianDay
398 : * @internal
399 : */
400 : double getJulianCentury();
401 :
402 : /**
403 : * Returns the current Greenwich sidereal time, measured in hours
404 : * @internal
405 : */
406 : double getGreenwichSidereal();
407 :
408 : private:
409 : double getSiderealOffset();
410 : public:
411 : /**
412 : * Returns the current local sidereal time, measured in hours
413 : * @internal
414 : */
415 : double getLocalSidereal();
416 :
417 : /**
418 : * Converts local sidereal time to Universal Time.
419 : *
420 : * @param lst The Local Sidereal Time, in hours since sidereal midnight
421 : * on this object's current date.
422 : *
423 : * @return The corresponding Universal Time, in milliseconds since
424 : * 1 Jan 1970, GMT.
425 : */
426 : //private:
427 : double lstToUT(double lst);
428 :
429 : /**
430 : *
431 : * Convert from ecliptic to equatorial coordinates.
432 : *
433 : * @param ecliptic The ecliptic
434 : * @param result Fillin result
435 : * @return reference to result
436 : */
437 : Equatorial& eclipticToEquatorial(Equatorial& result, const Ecliptic& ecliptic);
438 :
439 : /**
440 : * Convert from ecliptic to equatorial coordinates.
441 : *
442 : * @param eclipLong The ecliptic longitude
443 : * @param eclipLat The ecliptic latitude
444 : *
445 : * @return The corresponding point in equatorial coordinates.
446 : * @internal
447 : */
448 : Equatorial& eclipticToEquatorial(Equatorial& result, double eclipLong, double eclipLat);
449 :
450 : /**
451 : * Convert from ecliptic longitude to equatorial coordinates.
452 : *
453 : * @param eclipLong The ecliptic longitude
454 : *
455 : * @return The corresponding point in equatorial coordinates.
456 : * @internal
457 : */
458 : Equatorial& eclipticToEquatorial(Equatorial& result, double eclipLong) ;
459 :
460 : /**
461 : * @internal
462 : */
463 : Horizon& eclipticToHorizon(Horizon& result, double eclipLong) ;
464 :
465 : //-------------------------------------------------------------------------
466 : // The Sun
467 : //-------------------------------------------------------------------------
468 :
469 : /**
470 : * The longitude of the sun at the time specified by this object.
471 : * The longitude is measured in radians along the ecliptic
472 : * from the "first point of Aries," the point at which the ecliptic
473 : * crosses the earth's equatorial plane at the vernal equinox.
474 : * <p>
475 : * Currently, this method uses an approximation of the two-body Kepler's
476 : * equation for the earth and the sun. It does not take into account the
477 : * perturbations caused by the other planets, the moon, etc.
478 : * @internal
479 : */
480 : double getSunLongitude();
481 :
482 : /**
483 : * TODO Make this public when the entire class is package-private.
484 : */
485 : /*public*/ void getSunLongitude(double julianDay, double &longitude, double &meanAnomaly);
486 :
487 : /**
488 : * The position of the sun at this object's current date and time,
489 : * in equatorial coordinates.
490 : * @param result fillin for the result
491 : * @internal
492 : */
493 : Equatorial& getSunPosition(Equatorial& result);
494 :
495 : public:
496 : /**
497 : * Constant representing the vernal equinox.
498 : * For use with {@link #getSunTime getSunTime}.
499 : * Note: In this case, "vernal" refers to the northern hemisphere's seasons.
500 : * @internal
501 : */
502 : // static double VERNAL_EQUINOX();
503 :
504 : /**
505 : * Constant representing the summer solstice.
506 : * For use with {@link #getSunTime getSunTime}.
507 : * Note: In this case, "summer" refers to the northern hemisphere's seasons.
508 : * @internal
509 : */
510 : static double SUMMER_SOLSTICE();
511 :
512 : /**
513 : * Constant representing the autumnal equinox.
514 : * For use with {@link #getSunTime getSunTime}.
515 : * Note: In this case, "autumn" refers to the northern hemisphere's seasons.
516 : * @internal
517 : */
518 : // static double AUTUMN_EQUINOX();
519 :
520 : /**
521 : * Constant representing the winter solstice.
522 : * For use with {@link #getSunTime getSunTime}.
523 : * Note: In this case, "winter" refers to the northern hemisphere's seasons.
524 : * @internal
525 : */
526 : static double WINTER_SOLSTICE();
527 :
528 : /**
529 : * Find the next time at which the sun's ecliptic longitude will have
530 : * the desired value.
531 : * @internal
532 : */
533 : UDate getSunTime(double desired, UBool next);
534 :
535 : /**
536 : * Returns the time (GMT) of sunrise or sunset on the local date to which
537 : * this calendar is currently set.
538 : *
539 : * NOTE: This method only works well if this object is set to a
540 : * time near local noon. Because of variations between the local
541 : * official time zone and the geographic longitude, the
542 : * computation can flop over into an adjacent day if this object
543 : * is set to a time near local midnight.
544 : *
545 : * @internal
546 : */
547 : UDate getSunRiseSet(UBool rise);
548 :
549 : //-------------------------------------------------------------------------
550 : // The Moon
551 : //-------------------------------------------------------------------------
552 :
553 : /**
554 : * The position of the moon at the time set on this
555 : * object, in equatorial coordinates.
556 : * @internal
557 : * @return const reference to internal field of calendar astronomer. Do not use outside of the lifetime of this astronomer.
558 : */
559 : const Equatorial& getMoonPosition();
560 :
561 : /**
562 : * The "age" of the moon at the time specified in this object.
563 : * This is really the angle between the
564 : * current ecliptic longitudes of the sun and the moon,
565 : * measured in radians.
566 : *
567 : * @see #getMoonPhase
568 : * @internal
569 : */
570 : double getMoonAge();
571 :
572 : /**
573 : * Calculate the phase of the moon at the time set in this object.
574 : * The returned phase is a <code>double</code> in the range
575 : * <code>0 <= phase < 1</code>, interpreted as follows:
576 : * <ul>
577 : * <li>0.00: New moon
578 : * <li>0.25: First quarter
579 : * <li>0.50: Full moon
580 : * <li>0.75: Last quarter
581 : * </ul>
582 : *
583 : * @see #getMoonAge
584 : * @internal
585 : */
586 : double getMoonPhase();
587 :
588 : class U_I18N_API MoonAge : public UMemory {
589 : public:
590 0 : MoonAge(double l)
591 0 : : value(l) { }
592 : void set(double l) { value = l; }
593 : double value;
594 : };
595 :
596 : /**
597 : * Constant representing a new moon.
598 : * For use with {@link #getMoonTime getMoonTime}
599 : * @internal
600 : */
601 : static const MoonAge NEW_MOON();
602 :
603 : /**
604 : * Constant representing the moon's first quarter.
605 : * For use with {@link #getMoonTime getMoonTime}
606 : * @internal
607 : */
608 : // static const MoonAge FIRST_QUARTER();
609 :
610 : /**
611 : * Constant representing a full moon.
612 : * For use with {@link #getMoonTime getMoonTime}
613 : * @internal
614 : */
615 : static const MoonAge FULL_MOON();
616 :
617 : /**
618 : * Constant representing the moon's last quarter.
619 : * For use with {@link #getMoonTime getMoonTime}
620 : * @internal
621 : */
622 : // static const MoonAge LAST_QUARTER();
623 :
624 : /**
625 : * Find the next or previous time at which the Moon's ecliptic
626 : * longitude will have the desired value.
627 : * <p>
628 : * @param desired The desired longitude.
629 : * @param next <tt>true</tt> if the next occurrance of the phase
630 : * is desired, <tt>false</tt> for the previous occurrance.
631 : * @internal
632 : */
633 : UDate getMoonTime(double desired, UBool next);
634 : UDate getMoonTime(const MoonAge& desired, UBool next);
635 :
636 : /**
637 : * Returns the time (GMT) of sunrise or sunset on the local date to which
638 : * this calendar is currently set.
639 : * @internal
640 : */
641 : UDate getMoonRiseSet(UBool rise);
642 :
643 : //-------------------------------------------------------------------------
644 : // Interpolation methods for finding the time at which a given event occurs
645 : //-------------------------------------------------------------------------
646 :
647 : // private
648 : class AngleFunc : public UMemory {
649 : public:
650 : virtual double eval(CalendarAstronomer&) = 0;
651 : virtual ~AngleFunc();
652 : };
653 : friend class AngleFunc;
654 :
655 : UDate timeOfAngle(AngleFunc& func, double desired,
656 : double periodDays, double epsilon, UBool next);
657 :
658 : class CoordFunc : public UMemory {
659 : public:
660 : virtual void eval(Equatorial& result, CalendarAstronomer&) = 0;
661 : virtual ~CoordFunc();
662 : };
663 : friend class CoordFunc;
664 :
665 : double riseOrSet(CoordFunc& func, UBool rise,
666 : double diameter, double refraction,
667 : double epsilon);
668 :
669 : //-------------------------------------------------------------------------
670 : // Other utility methods
671 : //-------------------------------------------------------------------------
672 : private:
673 :
674 : /**
675 : * Return the obliquity of the ecliptic (the angle between the ecliptic
676 : * and the earth's equator) at the current time. This varies due to
677 : * the precession of the earth's axis.
678 : *
679 : * @return the obliquity of the ecliptic relative to the equator,
680 : * measured in radians.
681 : */
682 : double eclipticObliquity();
683 :
684 : //-------------------------------------------------------------------------
685 : // Private data
686 : //-------------------------------------------------------------------------
687 : private:
688 : /**
689 : * Current time in milliseconds since 1/1/1970 AD
690 : * @see java.util.Date#getTime
691 : */
692 : UDate fTime;
693 :
694 : /* These aren't used yet, but they'll be needed for sunset calculations
695 : * and equatorial to horizon coordinate conversions
696 : */
697 : double fLongitude;
698 : double fLatitude;
699 : double fGmtOffset;
700 :
701 : //
702 : // The following fields are used to cache calculated results for improved
703 : // performance. These values all depend on the current time setting
704 : // of this object, so the clearCache method is provided.
705 : //
706 :
707 : double julianDay;
708 : double julianCentury;
709 : double sunLongitude;
710 : double meanAnomalySun;
711 : double moonLongitude;
712 : double moonEclipLong;
713 : double meanAnomalyMoon;
714 : double eclipObliquity;
715 : double siderealT0;
716 : double siderealTime;
717 :
718 : void clearCache();
719 :
720 : Equatorial moonPosition;
721 : UBool moonPositionSet;
722 :
723 : /**
724 : * @internal
725 : */
726 : // UDate local(UDate localMillis);
727 : };
728 :
729 : U_NAMESPACE_END
730 :
731 : struct UHashtable;
732 :
733 : U_NAMESPACE_BEGIN
734 :
735 : /**
736 : * Cache of month -> julian day
737 : * @internal
738 : */
739 : class CalendarCache : public UMemory {
740 : public:
741 : static int32_t get(CalendarCache** cache, int32_t key, UErrorCode &status);
742 : static void put(CalendarCache** cache, int32_t key, int32_t value, UErrorCode &status);
743 : virtual ~CalendarCache();
744 : private:
745 : CalendarCache(int32_t size, UErrorCode& status);
746 : static void createCache(CalendarCache** cache, UErrorCode& status);
747 : /**
748 : * not implemented
749 : */
750 : CalendarCache();
751 : UHashtable *fTable;
752 : };
753 :
754 : U_NAMESPACE_END
755 :
756 : #endif
757 : #endif
|