| 1 | #include "slalib.h" | 
|---|
| 2 | #include "slamac.h" | 
|---|
| 3 | void slaDjcal ( int ndp, double djm, int iymdf[4], int *j ) | 
|---|
| 4 | /* | 
|---|
| 5 | **  - - - - - - - - - | 
|---|
| 6 | **   s l a D j c a l | 
|---|
| 7 | **  - - - - - - - - - | 
|---|
| 8 | ** | 
|---|
| 9 | **  Modified Julian Date to Gregorian calendar, expressed | 
|---|
| 10 | **  in a form convenient for formatting messages (namely | 
|---|
| 11 | **  rounded to a specified precision, and with the fields | 
|---|
| 12 | **  stored in a single array). | 
|---|
| 13 | ** | 
|---|
| 14 | **  Given: | 
|---|
| 15 | **     ndp      int       number of decimal places of days in fraction | 
|---|
| 16 | **     djm      double    Modified Julian Date (JD-2400000.5) | 
|---|
| 17 | ** | 
|---|
| 18 | **  Returned: | 
|---|
| 19 | **     iymdf    int[4]    year, month, day, fraction in Gregorian calendar | 
|---|
| 20 | **     *j       int       status:  nonzero = out of range | 
|---|
| 21 | ** | 
|---|
| 22 | **  Any date after 4701BC March 1 is accepted. | 
|---|
| 23 | ** | 
|---|
| 24 | **  Large ndp values risk internal overflows.  It is typically safe | 
|---|
| 25 | **  to use up to ndp=4. | 
|---|
| 26 | ** | 
|---|
| 27 | **  The algorithm is derived from that of Hatcher 1984 (QJRAS 25, 53-55). | 
|---|
| 28 | ** | 
|---|
| 29 | **  Defined in slamac.h:  dmod | 
|---|
| 30 | ** | 
|---|
| 31 | **  Last revision:   17 August 1999 | 
|---|
| 32 | ** | 
|---|
| 33 | **  Copyright P.T.Wallace.  All rights reserved. | 
|---|
| 34 | */ | 
|---|
| 35 | { | 
|---|
| 36 | double fd, df, f, d; | 
|---|
| 37 | long jd, n4, nd10; | 
|---|
| 38 |  | 
|---|
| 39 | /* Validate */ | 
|---|
| 40 | if ( ( djm <= -2395520.0 ) || ( djm >= 1.0e9 ) ) { | 
|---|
| 41 | *j = - 1; | 
|---|
| 42 | return; | 
|---|
| 43 | } else { | 
|---|
| 44 |  | 
|---|
| 45 | /* Denominator of fraction */ | 
|---|
| 46 | fd = pow ( 10.0, (double) gmax ( ndp, 0 ) ); | 
|---|
| 47 | fd = dnint ( fd ); | 
|---|
| 48 |  | 
|---|
| 49 | /* Round date and express in units of fraction */ | 
|---|
| 50 | df = djm * fd; | 
|---|
| 51 | df = dnint ( df ); | 
|---|
| 52 |  | 
|---|
| 53 | /* Separate day and fraction */ | 
|---|
| 54 | f = dmod ( df, fd ); | 
|---|
| 55 | if ( f < 0.0 ) f += fd; | 
|---|
| 56 | d = ( df - f ) / fd; | 
|---|
| 57 |  | 
|---|
| 58 | /* Express day in Gregorian calendar */ | 
|---|
| 59 | jd = (long) dnint ( d ) + 2400001L; | 
|---|
| 60 | n4 = 4L * ( jd + ( ( 2L * ( ( 4L * jd - 17918L ) / 146097L) | 
|---|
| 61 | * 3L ) / 4L + 1L ) / 2L - 37L ); | 
|---|
| 62 | nd10 = 10L * ( ( ( n4 - 237L ) % 1461L ) / 4L ) + 5L; | 
|---|
| 63 | iymdf[0] = (int) ( ( n4 / 1461L ) - 4712L ); | 
|---|
| 64 | iymdf[1] = (int) ( ( ( nd10 / 306L + 2L ) % 12L ) + 1L ); | 
|---|
| 65 | iymdf[2] = (int) ( ( nd10 % 306L ) / 10L + 1L ); | 
|---|
| 66 | iymdf[3] = (int) dnint ( f ); | 
|---|
| 67 | *j = 0; | 
|---|
| 68 | } | 
|---|
| 69 | } | 
|---|