pimappsupport/chinesecalendaralg/originalsrc/AstronomicalCal.cpp
branchRCL_3
changeset 12 38571fd2a704
equal deleted inserted replaced
5:42814f902fe6 12:38571fd2a704
       
     1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implementation of the TAstronomicalCalendar class.
       
    15 // 
       
    16 //
       
    17 
       
    18 // System includes
       
    19 #include <e32base.h>
       
    20 #include <e32math.h>
       
    21 
       
    22 // User includes
       
    23 #include "calconv.h"
       
    24 #include "calconvAstronomicalCal.h"
       
    25 
       
    26 // Constants
       
    27 const TReal KCoeff19th[] =
       
    28 	{
       
    29 	-0.00002,
       
    30 	0.000297,
       
    31 	0.025184,
       
    32 	-0.181133,
       
    33 	0.553040,
       
    34 	-0.861938,
       
    35 	0.677066,
       
    36 	-0.212591,
       
    37 	};
       
    38 
       
    39 const TReal KCoeff18th[] =
       
    40 	{
       
    41 	-0.000009,
       
    42 	0.003844,
       
    43 	0.083563,
       
    44 	0.865736,
       
    45 	4.867575,
       
    46 	15.845535,
       
    47 	31.332267,
       
    48 	38.291999,
       
    49 	28.316289,
       
    50 	11.636204,
       
    51 	2.043794,
       
    52 	};
       
    53 
       
    54 const TInt KCoeffs[] =
       
    55 	{
       
    56 	403406,
       
    57 	195207,
       
    58 	119433,
       
    59 	112392,
       
    60 	3891,
       
    61 	2819,
       
    62 	1721,
       
    63 	0,
       
    64 	660,
       
    65 	350,
       
    66 	334,
       
    67 	314,
       
    68 	268,
       
    69 	242,
       
    70 	234,
       
    71 	158,
       
    72 	132,
       
    73 	129,
       
    74 	114,
       
    75 	99,
       
    76 	93,
       
    77 	86,
       
    78 	78,
       
    79 	72,
       
    80 	68,
       
    81 	64,
       
    82 	46,
       
    83 	38,
       
    84 	37,
       
    85 	32,
       
    86 	29,
       
    87 	28,
       
    88 	27,
       
    89 	27,
       
    90 	25,
       
    91 	24,
       
    92 	21,
       
    93 	21,
       
    94 	20,
       
    95 	18,
       
    96 	17,
       
    97 	14,
       
    98 	13,
       
    99 	13,
       
   100 	13,
       
   101 	12,
       
   102 	10,
       
   103 	10,
       
   104 	10,
       
   105 	10,
       
   106 	};
       
   107 
       
   108 const TReal KMulti[] =
       
   109 	{
       
   110 	4.721964,
       
   111 	5.937458,
       
   112 	1.115589,
       
   113 	5.781616,
       
   114 	5.5474,
       
   115 	1.512,
       
   116 	4.1897,
       
   117 	1.163,
       
   118 	5.415,
       
   119 	4.315,
       
   120 	4.553,
       
   121 	5.198,
       
   122 	5.989,
       
   123 	2.911,
       
   124 	1.423,
       
   125 	0.061,
       
   126 	2.317,
       
   127 	3.193,
       
   128 	2.828,
       
   129 	0.52,
       
   130 	4.65,
       
   131 	4.35,
       
   132 	2.75,
       
   133 	4.5,
       
   134 	3.23,
       
   135 	1.22,
       
   136 	0.14,
       
   137 	3.44,
       
   138 	4.37,
       
   139 	1.14,
       
   140 	2.84,
       
   141 	5.96,
       
   142 	5.09,
       
   143 	1.72,
       
   144 	2.56,
       
   145 	1.92,
       
   146 	0.09,
       
   147 	5.98,
       
   148 	4.03,
       
   149 	4.47,
       
   150 	0.79,
       
   151 	4.24,
       
   152 	2.01,
       
   153 	2.65,
       
   154 	4.98,
       
   155 	0.93,
       
   156 	2.21,
       
   157 	3.59,
       
   158 	1.5,
       
   159 	2.55,
       
   160 	};
       
   161 
       
   162 const TReal KAdd[] =
       
   163 	{
       
   164 	0.01621043,
       
   165 	628.30348067,
       
   166 	628.30821524,
       
   167 	628.29634302,
       
   168 	1256.605691,
       
   169 	1256.60984,
       
   170 	628.324766,
       
   171 	0.00813,
       
   172 	1256.5931,
       
   173 	575.3385,
       
   174 	-0.33931,
       
   175 	7771.37715,
       
   176 	786.04191,
       
   177 	0.05412,
       
   178 	393.02098,
       
   179 	-0.34861,
       
   180 	1150.67698,
       
   181 	157.74337,
       
   182 	52.9667,
       
   183 	588.4927,
       
   184 	52.9611,
       
   185 	-39.807,
       
   186 	522.3769,
       
   187 	550.7647,
       
   188 	2.6108,
       
   189 	157.7385,
       
   190 	1884.9103,
       
   191 	-77.5655,
       
   192 	2.6489,
       
   193 	1179.0627,
       
   194 	550.7575,
       
   195 	-79.6139,
       
   196 	1884.8981,
       
   197 	21.3219,
       
   198 	1097.7103,
       
   199 	548.6856,
       
   200 	254.4393,
       
   201 	-557.3143,
       
   202 	606.9774,
       
   203 	21.3279,
       
   204 	1097.7163,
       
   205 	-77.5282,
       
   206 	1884.9191,
       
   207 	2.0781,
       
   208 	294.2463,
       
   209 	-0.0799,
       
   210 	469.4114,
       
   211 	-0.6829,
       
   212 	214.6325,
       
   213 	1572.084,
       
   214 	};
       
   215 
       
   216 const TReal KMuArray[] =
       
   217 	{
       
   218 	-0.40720,
       
   219 	0.17241,
       
   220 	0.01608,
       
   221 	0.01039,
       
   222 	0.00739,
       
   223 	-0.00514,
       
   224 	0.00208,
       
   225 	-0.00111,
       
   226 	-0.00057,
       
   227 	0.00056,
       
   228 	-0.00042,
       
   229 	0.00042,
       
   230 	0.00038,
       
   231 	-0.00024,
       
   232 	-0.00007,
       
   233 	0.00004,
       
   234 	0.00004,
       
   235 	0.00003,
       
   236 	0.00003,
       
   237 	-0.00003,
       
   238 	0.00003,
       
   239 	-0.00002,
       
   240 	-0.00002,
       
   241 	0.00002,
       
   242 	};
       
   243 
       
   244 const TInt8 KOmegaArray[] =
       
   245 	{
       
   246 	0,
       
   247 	1,
       
   248 	0,
       
   249 	0,
       
   250 	1,
       
   251 	1,
       
   252 	2,
       
   253 	0,
       
   254 	0,
       
   255 	1,
       
   256 	0,
       
   257 	1,
       
   258 	1,
       
   259 	1,
       
   260 	0,
       
   261 	0,
       
   262 	0,
       
   263 	0,
       
   264 	0,
       
   265 	0,
       
   266 	0,
       
   267 	0,
       
   268 	0,
       
   269 	0,
       
   270 	};
       
   271 
       
   272 const TInt8 KXiArray[] =
       
   273 	{
       
   274 	0,
       
   275 	1,
       
   276 	0,
       
   277 	0,
       
   278 	-1,
       
   279 	1,
       
   280 	2,
       
   281 	0,
       
   282 	0,
       
   283 	1,
       
   284 	0,
       
   285 	1,
       
   286 	1,
       
   287 	-1,
       
   288 	2,
       
   289 	0,
       
   290 	3,
       
   291 	1,
       
   292 	0,
       
   293 	1,
       
   294 	-1,
       
   295 	-1,
       
   296 	1,
       
   297 	0,
       
   298 	};
       
   299 
       
   300 const TInt8 KGammaArray[] =
       
   301 	{
       
   302 	1,
       
   303 	0,
       
   304 	2,
       
   305 	0,
       
   306 	1,
       
   307 	1,
       
   308 	0,
       
   309 	1,
       
   310 	1,
       
   311 	2,
       
   312 	3,
       
   313 	0,
       
   314 	0,
       
   315 	2,
       
   316 	1,
       
   317 	2,
       
   318 	0,
       
   319 	1,
       
   320 	2,
       
   321 	1,
       
   322 	1,
       
   323 	1,
       
   324 	3,
       
   325 	4,
       
   326 	};
       
   327 
       
   328 const TInt8 KZetaArray[] =
       
   329 	{
       
   330 	0,
       
   331 	0,
       
   332 	0,
       
   333 	2,
       
   334 	0,
       
   335 	0,
       
   336 	0,
       
   337 	-2,
       
   338 	2,
       
   339 	0,
       
   340 	0,
       
   341 	2,
       
   342 	-2,
       
   343 	0,
       
   344 	0,
       
   345 	-2,
       
   346 	0,
       
   347 	-2,
       
   348 	2,
       
   349 	2,
       
   350 	2,
       
   351 	-2,
       
   352 	0,
       
   353 	0,
       
   354 	};
       
   355 
       
   356 const TReal KIotaArray[] =
       
   357 	{
       
   358 	299.77,
       
   359 	251.88,
       
   360 	251.83,
       
   361 	349.42,
       
   362 	84.66,
       
   363 	141.74,
       
   364 	207.14,
       
   365 	154.84,
       
   366 	34.52,
       
   367 	207.19,
       
   368 	291.34,
       
   369 	161.72,
       
   370 	239.56,
       
   371 	331.55,
       
   372 	};
       
   373 
       
   374 const TReal KChiArray[] =
       
   375 	{
       
   376 	0.107408,
       
   377 	0.016321,
       
   378 	26.641886,
       
   379 	36.412478,
       
   380 	18.206239,
       
   381 	53.303771,
       
   382 	2.453732,
       
   383 	7.306860,
       
   384 	27.261239,
       
   385 	0.121824,
       
   386 	1.844379,
       
   387 	24.198154,
       
   388 	25.513099,
       
   389 	3.592518,
       
   390 	};
       
   391 
       
   392 const TReal KNuArray[] =
       
   393 	{
       
   394 	-0.009173,
       
   395 	0,
       
   396 	0,
       
   397 	0,
       
   398 	0,
       
   399 	0,
       
   400 	0,
       
   401 	0,
       
   402 	0,
       
   403 	0,
       
   404 	0,
       
   405 	0,
       
   406 	0,
       
   407 	0,
       
   408 	};
       
   409 
       
   410 const TReal KLamdaArray[] =
       
   411 	{
       
   412 	0.000325,
       
   413 	0.000165,
       
   414 	0.000164,
       
   415 	0.000126,
       
   416 	0.00011,
       
   417 	0.000062,
       
   418 	0.00006,
       
   419 	0.000056,
       
   420 	0.000047,
       
   421 	0.000042,
       
   422 	0.00004,
       
   423 	0.000037,
       
   424 	0.000035,
       
   425 	0.000023,
       
   426 	};
       
   427 
       
   428 const TInt  KInitOne				= 1;
       
   429 const TInt KHoursInDay				= 24;
       
   430 const TInt KMinsInHour				= 60;
       
   431 const TInt KSecsInMin				= 60;
       
   432 const TInt KDaysInGregHundredYears	= 36525;
       
   433 const TReal KMeanDaysInGregYear		= 365.25;
       
   434 const TInt  KSquared				= 2;
       
   435 const TInt  KCubed					= 3;
       
   436 const TInt  KQuad					= 4;
       
   437 const TInt K360Degrees				= 360;
       
   438 const TReal KDegreesToRadians		= 0.017453292519943296; //(KPi/180);
       
   439 const TInt  KNumElementsCoeff19th	= 8;
       
   440 const TInt  KNumElementsCoeff18th	= 11;
       
   441 const TInt  KNoOfPeriodicTerms		= 50;
       
   442 const TInt  KMaxCorrectionValues	= 24;
       
   443 const TReal KMonthsInTropicalYear	= 12.3685;
       
   444 const TInt  KMaxAdditionalValues	= 14;
       
   445 
       
   446 //
       
   447 // Construction/Destruction
       
   448 //
       
   449 
       
   450 //------------------------------------------------------
       
   451 // Class:       TAstronomicalCalendar
       
   452 // Function:    TAstronomicalCalendar
       
   453 // Arguments:   None
       
   454 //
       
   455 // Comments:    Constructor
       
   456 //
       
   457 // Return:      None
       
   458 //------------------------------------------------------
       
   459 TAstronomicalCalendar::TAstronomicalCalendar()
       
   460 	{
       
   461 
       
   462 	}
       
   463 
       
   464 //------------------------------------------------------
       
   465 // Class:       TAstronomicalCalendar
       
   466 // Function:    UniversalFromLocal
       
   467 // Arguments:   TReal , TInt 
       
   468 //
       
   469 // Comments:    Universal time is used for time keeping purposes.
       
   470 //				It is given as a fraction on a solar day
       
   471 //
       
   472 // Return:      Universal time
       
   473 //------------------------------------------------------
       
   474 TReal TAstronomicalCalendar::UniversalFromLocal(const TReal& aTime,const TReal& aZone) const
       
   475 	{
       
   476 	return (aTime - (aZone / (KHoursInDay * KMinsInHour)));
       
   477 	}
       
   478 
       
   479 //------------------------------------------------------
       
   480 // Class:       TAstronomicalCalendar
       
   481 // Function:    LocalFromUniversal
       
   482 // Arguments:   TReal , TInt 
       
   483 //
       
   484 // Comments:    Universal time is used for time keeping purposes.
       
   485 //				It is given as a fraction on a solar day
       
   486 //
       
   487 // Return:      Local time
       
   488 //------------------------------------------------------
       
   489 TReal TAstronomicalCalendar::LocalFromUniversal(const TReal& aTime, const TReal& aZone) const
       
   490 	{
       
   491 	return (aTime + (aZone / (KHoursInDay * KMinsInHour)));
       
   492 	}
       
   493 
       
   494 //------------------------------------------------------
       
   495 // Class:       TAstronomicalCalendarL
       
   496 // Function:    EphemerisCorrection
       
   497 // Arguments:   TReal 
       
   498 //
       
   499 // Comments:    Astronomical calculations are performed using
       
   500 //				Ephemeris time that is not affected by nutation
       
   501 //				and aberation. 
       
   502 //
       
   503 // Return:      Correction value
       
   504 //------------------------------------------------------
       
   505 void TAstronomicalCalendar::EphemerisCorrection(const TReal aJulianDay, TReal& aCorrection) const
       
   506 	{
       
   507 	TGregorianCalendar greg(aJulianDay);
       
   508 	TArithmeticalDate gregDate;
       
   509 	TInt year;
       
   510 	TReal theta;
       
   511 	TReal x;
       
   512 	aCorrection = 0;
       
   513 
       
   514 	// get the value for the year
       
   515 	greg.GetDate(gregDate);
       
   516 	year = gregDate.iYear;
       
   517 	// get theta value
       
   518 	PopulateTheta(theta,year);
       
   519 	// get x value
       
   520 	EphemerisCorrPopX(year, x);
       
   521 
       
   522 	// perform ephemeris correction
       
   523 	if((year >= 1988) && (year <= 2019))
       
   524 		{
       
   525 		aCorrection = ((year - 1933) / (KHoursInDay * KMinsInHour * KSecsInMin));
       
   526 		}
       
   527 	else if((year >= 1900) && (year <= 1987))
       
   528 		{
       
   529 		GetPoly(KCoeff19th,theta,KNumElementsCoeff19th,aCorrection);
       
   530 		}
       
   531 	else if((year >= 1800) && (year <= 1899))
       
   532 		{
       
   533 		GetPoly(KCoeff18th,theta,KNumElementsCoeff18th, aCorrection);
       
   534 		}
       
   535 	else if((year >= 1620) && (year <= 1799))
       
   536 		{
       
   537 		TReal result;
       
   538 		result = year - 1600;
       
   539 		Math::Pow(result,result,KSquared);
       
   540 		result = 196.58333 - (4.0675 * (year - 1600)) + 0.0219167 * result;
       
   541 		aCorrection = result / (KHoursInDay * KMinsInHour * KSecsInMin);
       
   542 		}
       
   543 	else
       
   544 		{
       
   545 		TReal result;
       
   546 		Math::Pow(result,x,KSquared);
       
   547 		result = (result / 41048480) - 15;
       
   548 		aCorrection = result / (KHoursInDay * KMinsInHour * KSecsInMin);
       
   549 		}
       
   550 	}
       
   551 
       
   552 //------------------------------------------------------
       
   553 // Class:       TAstronomicalCalendar
       
   554 // Function:    PopulateTheta
       
   555 // Arguments:   TReal&
       
   556 //
       
   557 // Comments:    Determines the constant for theta
       
   558 //				This function is used for the ephemeris correction
       
   559 //
       
   560 // Return:      None
       
   561 //------------------------------------------------------
       
   562 void TAstronomicalCalendar::PopulateTheta(TReal &aTheta,TInt aYear) const
       
   563 	{
       
   564 	TGregorianCalendar greg;
       
   565 	TArithmeticalDate gregDate1;
       
   566 	TArithmeticalDate gregDate2;
       
   567 	gregDate1.iDay = KCalConvFirstDay;
       
   568 	gregDate1.iMonth = EJanuary + KCalConvMonthOffsetByOne;
       
   569 	gregDate1.iYear = 1900;
       
   570 	gregDate2.iDay = KCalConvFirstDay;
       
   571 	gregDate2.iMonth = EJuly + KCalConvMonthOffsetByOne;
       
   572 	gregDate2.iYear = aYear;
       
   573 	aTheta = greg.GregDateDiff(gregDate1,gregDate2) / KDaysInGregHundredYears;
       
   574 	}
       
   575 
       
   576 //------------------------------------------------------
       
   577 // Class:       TAstronomicalCalendar
       
   578 // Function:    EphemerisCorrPopX
       
   579 // Arguments:   TReal&
       
   580 //
       
   581 // Comments:    Determines the constant for x
       
   582 //				This function is used for the ephemeris correction
       
   583 //
       
   584 // Return:      TReal - ephemeris constant
       
   585 //------------------------------------------------------
       
   586 void TAstronomicalCalendar::EphemerisCorrPopX(const TInt aYear, TReal& aEmphCorr) const
       
   587 	{
       
   588 	TGregorianCalendar greg;
       
   589 	TArithmeticalDate gregDate1;
       
   590 	TArithmeticalDate gregDate2;
       
   591 	gregDate1.iDay = KCalConvFirstDay;
       
   592 	gregDate1.iMonth = EJanuary + KCalConvMonthOffsetByOne;
       
   593 	gregDate1.iYear = 1810;
       
   594 	gregDate2.iDay = KCalConvFirstDay;
       
   595 	gregDate2.iMonth = EJanuary + KCalConvMonthOffsetByOne;
       
   596 	gregDate2.iYear = aYear;
       
   597 	aEmphCorr = 0.5 + greg.GregDateDiff(gregDate1,gregDate2);
       
   598 	}
       
   599 
       
   600 //------------------------------------------------------
       
   601 // Class:       TAstronomicalCalendar
       
   602 // Function:    GetPoly
       
   603 // Arguments:   TReal& , CArrayFixFlat<TReal>& , TReal&
       
   604 //
       
   605 // Comments:    performs the following calculation
       
   606 //
       
   607 //										 2
       
   608 //				SIGMA (Array[i] * Operand )
       
   609 //				   i
       
   610 //
       
   611 // Return:      TReal - result of above calculation
       
   612 //------------------------------------------------------
       
   613 void TAstronomicalCalendar::GetPoly(const TReal* aArray,const TReal& aOperand, TInt aCount, TReal& aResult) const
       
   614 	{
       
   615 	TInt count;
       
   616 	TReal poly;
       
   617 
       
   618 	aResult = aArray[0];
       
   619 	for(count = KInitOne; count < aCount; count++)
       
   620 		{
       
   621 		Math::Pow(poly,aOperand,count);
       
   622 		aResult += aArray[count] * poly;
       
   623 		}
       
   624 	}
       
   625 
       
   626 //------------------------------------------------------
       
   627 // Class:       TAstronomicalCalendar
       
   628 // Function:    EphemerisFromUniversal
       
   629 // Arguments:   None
       
   630 //
       
   631 // Comments:    converts ephemeris time to universal time
       
   632 //
       
   633 // Return:      TReal - universal time
       
   634 //------------------------------------------------------
       
   635 void TAstronomicalCalendar::EphemerisFromUniversal(const TReal& aJulianDay, TReal& aCorrectedJD) const
       
   636 	{
       
   637 	TReal emphCorr;
       
   638 	EphemerisCorrection(aJulianDay, emphCorr);
       
   639 	aCorrectedJD = aJulianDay + emphCorr;
       
   640 	}
       
   641 
       
   642 //------------------------------------------------------
       
   643 // Class:       TAstronomicalCalendar
       
   644 // Function:    UniversalFromEphemeris
       
   645 // Arguments:   None
       
   646 //
       
   647 // Comments:    Converts universal time to ephemeris time
       
   648 //
       
   649 // Return:      TReal - ephemeris time
       
   650 //------------------------------------------------------
       
   651 TReal TAstronomicalCalendar::UniversalFromEphemeris(const TReal& aJulianDay) const
       
   652 	{
       
   653 	TReal result;
       
   654 	EphemerisCorrection(aJulianDay, result);
       
   655 	return (aJulianDay - result);
       
   656 	}
       
   657 
       
   658 
       
   659 //------------------------------------------------------
       
   660 // Class:       TAstronomicalCalendar
       
   661 // Function:    j2000
       
   662 // Arguments:   None
       
   663 //
       
   664 // Comments:    Julian day value of January 1st 2000
       
   665 //
       
   666 // Return:      TReal - see comment
       
   667 //------------------------------------------------------
       
   668 void TAstronomicalCalendar::j2000(TReal& aJ2000) const
       
   669 	{
       
   670 	TGregorianCalendar greg;
       
   671 	TArithmeticalDate date;
       
   672 
       
   673 	date.iDay = KCalConvFirstDay;
       
   674 	date.iMonth = EJanuary + KCalConvMonthOffsetByOne;
       
   675 	date.iYear = 2000;
       
   676 
       
   677 	aJ2000 = KCalConvPointFive + greg.GregToJulianDay(date);
       
   678 
       
   679 	AdjustJDToNoon(aJ2000);
       
   680 	}
       
   681 
       
   682 //------------------------------------------------------
       
   683 // Class:       TAstronomicalCalendar
       
   684 // Function:    JulianCenturies
       
   685 // Arguments:   None
       
   686 //
       
   687 // Comments:    Number of centuries before or after January
       
   688 //				1st 2000 (Gregorian)
       
   689 //
       
   690 // Return:      TReal - centuries and fraction thereof
       
   691 //------------------------------------------------------
       
   692 void TAstronomicalCalendar::JulianCenturies(const TReal& aJulianDay, TReal& aJC) const
       
   693 	{
       
   694 	TReal emph;
       
   695 	TReal julian2000;
       
   696 	EphemerisFromUniversal(aJulianDay,emph);
       
   697 	j2000(julian2000);
       
   698 
       
   699 	aJC = ( emph- julian2000) / KDaysInGregHundredYears;
       
   700 	}
       
   701 
       
   702 //------------------------------------------------------
       
   703 // Class:       TAstronomicalCalendar
       
   704 // Function:    SolarLongitudeL
       
   705 // Arguments:   TReal&
       
   706 //
       
   707 // Comments:    calculates the longitude of the sun at 
       
   708 //				any give Julian Day value.
       
   709 //
       
   710 // Return:      TReal - longitude
       
   711 //------------------------------------------------------
       
   712 void TAstronomicalCalendar::SolarLongitude(const TReal& aJulianDay, TReal& aTheta) const
       
   713 	{
       
   714 	TReal centuries;  // Julian centuries
       
   715 	TReal longitude;  // longitude
       
   716 	TReal aberration;
       
   717 	TReal nutation;
       
   718 
       
   719 	// get the julian centuries
       
   720 	JulianCenturies(aJulianDay,centuries);
       
   721 
       
   722 	// get the longitude
       
   723 	GetLongitude(centuries, longitude);
       
   724 
       
   725 	Aberration(centuries,aberration);
       
   726 	Nutation(centuries,nutation);
       
   727 
       
   728 	aTheta = (longitude + aberration + nutation);
       
   729 	aTheta = (aTheta / KPi) * 180;
       
   730 	Mod(aTheta,aTheta,K360Degrees);
       
   731 	}
       
   732 
       
   733 //------------------------------------------------------
       
   734 // Class:       TAstronomicalCalendar
       
   735 // Function:    Nutation
       
   736 // Arguments:   TReal &
       
   737 //
       
   738 // Comments:    corrects for changes in celestial longitude
       
   739 //				and latitude caused by the gravitational pull
       
   740 //				of the sun and moon on the earth.
       
   741 //
       
   742 // Return:      TReal - correction value
       
   743 //------------------------------------------------------
       
   744 void TAstronomicalCalendar::Nutation(const TReal &aJulianCenturies, TReal& aNutation) const
       
   745 	{
       
   746 	TReal a;
       
   747 	TReal b;
       
   748 
       
   749 	a = 124.9 - (1934.134 * aJulianCenturies) + (0.002063 * aJulianCenturies * aJulianCenturies);
       
   750 	a *=KDegreesToRadians;
       
   751 	Math::Sin(a,a);
       
   752 
       
   753 	b = 201.11 + (72001.5377 * aJulianCenturies) + (0.00057 * aJulianCenturies * aJulianCenturies);
       
   754 	b *= KDegreesToRadians;
       
   755 	Math::Sin(b,b);
       
   756 
       
   757 	aNutation = (-0.0000834 * a) - (0.0000064 * b);
       
   758 	}
       
   759 
       
   760 //------------------------------------------------------
       
   761 // Class:       TAstronomicalCalendar
       
   762 // Function:    Aberration
       
   763 // Arguments:   TReal &
       
   764 //
       
   765 // Comments:    This function makes a correction for the 
       
   766 //				movement of the earth (the apparent movement
       
   767 //				of the sun) in the time taken for light to 
       
   768 //				travel to earth.
       
   769 //
       
   770 // Return:      TReal - correction in radians
       
   771 //------------------------------------------------------
       
   772 void TAstronomicalCalendar::Aberration(const TReal &aJulianCenturies, TReal& aAberration) const
       
   773 	{
       
   774 	aAberration = 177.63 + (35999.01848 * aJulianCenturies);
       
   775 	aAberration *= KDegreesToRadians;
       
   776 	Math::Cos(aAberration,aAberration);
       
   777 	aAberration = (0.0000017 * aAberration) - 0.0000973;
       
   778 	}
       
   779 
       
   780 //------------------------------------------------------
       
   781 // Class:       TAstronomicalCalendar
       
   782 // Function:    GetLongitude
       
   783 // Arguments:   TReal&
       
   784 //
       
   785 // Comments:    calculates the longitude component of the 
       
   786 //				solar longitude calculation.
       
   787 //				This function is used by the SolarLongitudeL 
       
   788 //				function.
       
   789 //
       
   790 // Return:      TReal - longitude
       
   791 //------------------------------------------------------
       
   792 void TAstronomicalCalendar::GetLongitude(const TReal& aC, TReal& aLongitude) const
       
   793 	{
       
   794 	TInt count;
       
   795 	aLongitude = 0;
       
   796 
       
   797 	// get longitude
       
   798 	for(count = 0;count < KNoOfPeriodicTerms;count++)
       
   799 		{
       
   800 		TReal temp;
       
   801 		temp = (KMulti[count] + (KAdd[count] * aC));
       
   802 		// convert to radians for the Sin function
       
   803 		Math::Sin(temp,temp);
       
   804 		temp = KCoeffs[count] * temp;
       
   805 		aLongitude += temp;
       
   806 		}
       
   807 	aLongitude = 4.9353929 + (628.33196168 * aC) + (0.0000001 * aLongitude);
       
   808 	}
       
   809 
       
   810 //------------------------------------------------------
       
   811 // Class:       TAstronomicalCalendar
       
   812 // Function:    DateNextSolarLongitudeL
       
   813 // Arguments:   TReal , TReal
       
   814 //
       
   815 // Comments:    
       
   816 //
       
   817 // Return:      TReal
       
   818 //------------------------------------------------------
       
   819 TReal TAstronomicalCalendar::DateNextSolarLongitude(const TReal& aJulianDay,const TReal& aDegrees) const
       
   820 	{
       
   821 	TReal next;
       
   822 	TInt nextInt;
       
   823 	TReal upperLimit;
       
   824 	TReal lowerLimit;
       
   825 	TReal testDate;
       
   826 
       
   827 	// get next
       
   828 	SolarLongitude(aJulianDay,next);
       
   829 	next/= aDegrees;
       
   830 	Ceiling(nextInt,next);
       
   831 	next = nextInt * aDegrees;
       
   832 	Mod(next,next,K360Degrees);
       
   833 
       
   834 	// this is designed to define a range (aJulianDay -> UpperLimit) 
       
   835 	// that will allow the sun to pass though aDegrees once and once only
       
   836 	upperLimit = aJulianDay + ((aDegrees / K360Degrees) * 400);
       
   837 	lowerLimit = aJulianDay;
       
   838 
       
   839 	for(testDate = (upperLimit + lowerLimit) / 2;
       
   840 		(upperLimit - lowerLimit) >= 0.00001;
       
   841 		testDate = (upperLimit + lowerLimit) / 2)
       
   842 		{
       
   843 		TReal solLong;
       
   844 		SolarLongitude(testDate, solLong);
       
   845 		if(next == 0)
       
   846 			{
       
   847 			if(solLong <= aDegrees)
       
   848 				{
       
   849 				upperLimit = testDate;
       
   850 				}
       
   851 			else
       
   852 				{
       
   853 				lowerLimit = testDate;
       
   854 				}
       
   855 			}
       
   856 		else
       
   857 			{
       
   858 			if(solLong >= next)
       
   859 				{
       
   860 				upperLimit = testDate;
       
   861 				}
       
   862 			else
       
   863 				{
       
   864 				lowerLimit = testDate;
       
   865 				}
       
   866 			}
       
   867 		}
       
   868 	return testDate;
       
   869 	}
       
   870 
       
   871 //------------------------------------------------------
       
   872 // Class:       TAstronomicalCalendar
       
   873 // Function:    NewMoonAtOrAfter
       
   874 // Arguments:   TReal& 
       
   875 //
       
   876 // Comments:    Calculates the time of the new moon by deturmining
       
   877 //				the sums of periodic terms.
       
   878 //
       
   879 // Return:      TReal - time of new moon
       
   880 //------------------------------------------------------
       
   881 TReal TAstronomicalCalendar::NewMoonAtOrAfter(const TReal& aJulianDay) const
       
   882 	{
       
   883 	TReal jDReal = aJulianDay;
       
   884 	TReal result;
       
   885 	TInt jD;
       
   886 
       
   887 
       
   888 	AdjustJDFromNoon(jDReal);
       
   889 	Floor(jD,jDReal);
       
   890 	TGregorianCalendar greg(jDReal);
       
   891 	AdjustJDToNoon(jDReal);
       
   892 
       
   893 	TArithmeticalDate date;
       
   894 	TInt approx;
       
   895 	TInt error;
       
   896 	TReal gamma;
       
   897 
       
   898 	TReal temp;
       
   899 	TInt count;
       
   900 
       
   901 	// get date
       
   902 	greg.GetDate(date);
       
   903 
       
   904 	// get Gamma
       
   905 	gamma = date.iYear + (greg.DayNumber(date) / KMeanDaysInGregYear) - 2000;
       
   906 
       
   907 	// get approx
       
   908 	temp = gamma * KMonthsInTropicalYear;
       
   909 	Floor(approx,temp);
       
   910 	approx--;
       
   911 
       
   912 	// get error
       
   913 	error = 0;
       
   914 
       
   915 	for(count = approx;NewMoonTime(count) < aJulianDay;count++)
       
   916 		{
       
   917 		error++;
       
   918 		}
       
   919 
       
   920 	// calc return
       
   921 	result = NewMoonTime(approx + error);
       
   922 	return result;
       
   923 	}
       
   924 
       
   925 //------------------------------------------------------
       
   926 // Class:       TAstronomicalCalendar
       
   927 // Function:    NewMoonTime
       
   928 // Arguments:   TInt
       
   929 //
       
   930 // Comments:    This function is used as part of the calculation
       
   931 //				for NewMoonAtOrAfter()
       
   932 //
       
   933 // Return:      TReal - derived value
       
   934 //------------------------------------------------------
       
   935 TReal TAstronomicalCalendar::NewMoonTime(TInt aTime) const
       
   936 	{
       
   937 	TReal newMoonTime;
       
   938 	TReal kappa;
       
   939 	TReal jde;
       
   940 	TReal epsilon;
       
   941 	TReal solarAnomaly;
       
   942 	TReal lunarAnomaly;
       
   943 	TReal moonArgument;
       
   944 	TReal omega;
       
   945 	TReal correction;
       
   946 	TReal additional;
       
   947 
       
   948 	TReal temp;
       
   949 	TInt count;
       
   950 
       
   951 	// get Kappa
       
   952 	kappa = aTime / 1236.85;
       
   953 
       
   954 	// get jde
       
   955 	jde = 2451550.09765;
       
   956 	temp = KMeanSynodicMonth * 1236.85 * kappa;
       
   957 	jde += temp;
       
   958 	Math::Pow(temp,kappa,KSquared);
       
   959 	jde += temp * 0.0001337;
       
   960 	Math::Pow(temp,kappa,KCubed);
       
   961 	jde -= temp * 0.00000015;
       
   962 	Math::Pow(temp,kappa,KQuad);
       
   963 	jde += temp * 0.00000000073;
       
   964 
       
   965 	// get epsilon
       
   966 	epsilon = 1 - (0.002516 * kappa);
       
   967 	Math::Pow(temp,kappa,KSquared);
       
   968 	epsilon -= temp * 0.0000074;
       
   969 
       
   970 	// get solar anomaly
       
   971 	solarAnomaly = 2.5534 + (29.10535669 * 1236.85 * kappa);
       
   972 	Math::Pow(temp,kappa,KSquared);
       
   973 	solarAnomaly -= temp * 0.0000218;
       
   974 	Math::Pow(temp,kappa,KCubed);
       
   975 	solarAnomaly -= temp * 0.00000011;
       
   976 
       
   977 	// get lunar anomaly
       
   978 	lunarAnomaly = 201.5643 + (385.81693528 * 1236.85 * kappa);
       
   979 	Math::Pow(temp,kappa,KSquared);
       
   980 	lunarAnomaly += temp * 0.0107438;
       
   981 	Math::Pow(temp,kappa,KCubed);
       
   982 	lunarAnomaly += temp * 0.00001239;
       
   983 	Math::Pow(temp,kappa,KQuad);
       
   984 	lunarAnomaly -= temp * 0.000000058;
       
   985 
       
   986 	// get moon argument
       
   987 	moonArgument = 160.7108 + (390.67050274 * 1236.85 * kappa);
       
   988 	Math::Pow(temp,kappa,KSquared);
       
   989 	moonArgument -= temp * 0.0016341;
       
   990 	Math::Pow(temp,kappa,KCubed);
       
   991 	moonArgument -= temp * 0.00000227;
       
   992 	Math::Pow(temp,kappa,KQuad);
       
   993 	moonArgument += temp * 0.000000011;
       
   994 
       
   995 	// get omega
       
   996 	omega = 124.7746 + (-1.5637558 * 1236.85 * kappa);
       
   997 	Math::Pow(temp,kappa,KSquared);
       
   998 	omega += temp * 0.0020691;
       
   999 	Math::Pow(temp,kappa,KCubed);
       
  1000 	omega += temp * 0.00000215;
       
  1001 
       
  1002 	// convert to radians for the Sin function
       
  1003 	omega *= KDegreesToRadians;
       
  1004 	Math::Sin(correction,omega);
       
  1005 	correction = -0.00017 * correction;
       
  1006 	for(count = 0; count < KMaxCorrectionValues;count++)
       
  1007 		{
       
  1008 		TReal tempCorrection;
       
  1009 		TReal epsilonToTheOmega;
       
  1010 		tempCorrection = (KXiArray[count] * solarAnomaly) + 
       
  1011 						(KGammaArray[count] * lunarAnomaly) +
       
  1012 						(KZetaArray[count] * moonArgument);
       
  1013 		// convert to radians for the Sin function
       
  1014 		tempCorrection *= KDegreesToRadians;
       
  1015 		Math::Sin(tempCorrection,tempCorrection);
       
  1016 		Math::Pow(epsilonToTheOmega,epsilon,KOmegaArray[count]);
       
  1017 		tempCorrection = KMuArray[count] * epsilonToTheOmega * tempCorrection;
       
  1018 		correction += tempCorrection;
       
  1019 		}
       
  1020 	
       
  1021 	for(count = 0,additional = 0;count < KMaxAdditionalValues;count++)
       
  1022 		{
       
  1023 		TReal addnTemp;
       
  1024 		Math::Pow(addnTemp,kappa,KSquared);
       
  1025 		addnTemp = KIotaArray[count] + (KChiArray[count] * aTime) +
       
  1026 					(KNuArray[count] * addnTemp);
       
  1027 		// convert to radians for the Sin function
       
  1028 		addnTemp *= KDegreesToRadians;
       
  1029 		Math::Sin(addnTemp,addnTemp);
       
  1030 		addnTemp = KLamdaArray[count] * addnTemp;
       
  1031 		additional += addnTemp;
       
  1032 		}
       
  1033 
       
  1034 	// calculate result
       
  1035 	newMoonTime = jde + correction + additional;
       
  1036 	newMoonTime = UniversalFromEphemeris(newMoonTime);
       
  1037 	return newMoonTime;
       
  1038 	}
       
  1039 
       
  1040 //------------------------------------------------------
       
  1041 // Class:       TAstronomicalCalendar
       
  1042 // Function:    NewMoonBefore
       
  1043 // Arguments:   
       
  1044 //
       
  1045 // Comments:    
       
  1046 //
       
  1047 // Return:      
       
  1048 //------------------------------------------------------
       
  1049 TReal TAstronomicalCalendar::NewMoonBefore(const TReal &aJulianDay) const
       
  1050 	{
       
  1051 	TReal result;
       
  1052 	result = NewMoonAtOrAfter(aJulianDay);
       
  1053 	result-=45;
       
  1054 	result = NewMoonAtOrAfter(result);
       
  1055 	return result;
       
  1056 	}
       
  1057 
       
  1058 //------------------------------------------------------
       
  1059 // Class:       TAstronomicalCalendar
       
  1060 // Function:    AdjustJDToNoon
       
  1061 // Arguments:   TReal&
       
  1062 //
       
  1063 // Comments:    This function corrects for the fact that the
       
  1064 //				julian day starts at noon however the julian
       
  1065 //				day held in the base class starts on the 
       
  1066 //				preceeding midnight.
       
  1067 //
       
  1068 // Return:      None
       
  1069 //------------------------------------------------------
       
  1070 void TAstronomicalCalendar::AdjustJDToNoon(TReal &aJulianDay) const
       
  1071 	{
       
  1072 	aJulianDay -= KCalConvPointFive;
       
  1073 	}
       
  1074 
       
  1075 //------------------------------------------------------
       
  1076 // Class:       TAstronomicalCalendar
       
  1077 // Function:    AdjustJDFromNoon
       
  1078 // Arguments:   TReal&
       
  1079 //
       
  1080 // Comments:    This function corrects for the fact that the
       
  1081 //				julian day starts at noon however the julian
       
  1082 //				day held in the base class starts on the 
       
  1083 //				preceeding midnight.
       
  1084 //
       
  1085 // Return:      None
       
  1086 //------------------------------------------------------
       
  1087 void TAstronomicalCalendar::AdjustJDFromNoon(TReal &aJulianDay) const
       
  1088 	{
       
  1089 	aJulianDay += KCalConvPointFive;
       
  1090 	}