1 /* etcal.f -- translated by f2c (version 19980913).
2    You must link the resulting object file with the libraries:
3 	-lf2c -lm   (in that order)
4 */
5 
6 #include "f2c.h"
7 
8 /* Table of constant values */
9 
10 static integer c__2000 = 2000;
11 static integer c__1 = 1;
12 static integer c__12 = 12;
13 static integer c__6 = 6;
14 
15 /* $Procedure            ETCAL ( Convert ET to Calendar format ) */
etcal_(doublereal * et,char * string,ftnlen string_len)16 /* Subroutine */ int etcal_(doublereal *et, char *string, ftnlen string_len)
17 {
18     /* Initialized data */
19 
20     static logical first = TRUE_;
21     static integer extra[12] = { 0,0,1,1,1,1,1,1,1,1,1,1 };
22     static integer dpjan0[12] = { 0,31,59,90,120,151,181,212,243,273,304,334 }
23 	    ;
24     static integer dpbegl[12] = { 0,31,60,91,121,152,182,213,244,274,305,335 }
25 	    ;
26     static char months[3*12] = "JAN" "FEB" "MAR" "APR" "MAY" "JUN" "JUL"
27 	    "AUG" "SEP" "OCT" "NOV" "DEC";
28 
29     /* System generated locals */
30     address a__1[12];
31     integer i__1, i__2, i__3[12];
32     doublereal d__1;
33 
34     /* Builtin functions */
35     integer s_rnge(char *, integer, char *, integer);
36     double d_int(doublereal *);
37     /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen), s_cat(char *,
38 	     char **, integer *, integer *, ftnlen);
39 
40     /* Local variables */
41     static integer dn2000;
42     static doublereal dp2000, frac;
43     static char date[180];
44     static doublereal remd, secs;
45     static integer year, mins;
46     static char dstr[16], hstr[16], mstr[16], sstr[16], ystr[16];
47     static doublereal halfd, q;
48     static integer tsecs, dofyr, month, hours;
49     extern /* Subroutine */ int ljust_(char *, char *, ftnlen, ftnlen);
50     static doublereal mynum;
51     static integer bh, bm, iq;
52     static doublereal secspd;
53     static char messge[16];
54     static integer offset;
55     static doublereal dmnint;
56     static logical adjust;
57     static integer daynum;
58     extern integer intmin_(void), intmax_(void);
59     extern /* Subroutine */ int dpstrf_(doublereal *, integer *, char *, char
60 	    *, ftnlen, ftnlen);
61     static doublereal dmxint, mydnom;
62     extern /* Subroutine */ int cmprss_(char *, integer *, char *, char *,
63 	    ftnlen, ftnlen, ftnlen);
64     extern integer lstlti_(integer *, integer *, integer *);
65     extern /* Subroutine */ int intstr_(integer *, char *, ftnlen);
66     static integer yr1, yr4;
67     static char era[16];
68     static integer day, rem;
69     extern doublereal spd_(void);
70     static integer yr100, yr400;
71 
72 /* $ Abstract */
73 
74 
75 /*     Convert from an ephemeris epoch measured in seconds past */
76 /*     the epoch of J2000 to a calendar string format using a */
77 /*     formal calendar free of leapseconds. */
78 
79 /* $ Disclaimer */
80 
81 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
82 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
83 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
84 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
85 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
86 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
87 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
88 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
89 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
90 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
91 
92 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
93 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
94 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
95 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
96 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
97 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
98 
99 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
100 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
101 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
102 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
103 
104 /* $ Required_Reading */
105 
106 /*     None. */
107 
108 /* $ Keywords */
109 
110 /*     TIME */
111 
112 /* $ Declarations */
113 /* $ Brief_I/O */
114 
115 /*     Variable  I/O  Description */
116 /*     --------  ---  -------------------------------------------------- */
117 /*     ET         I   Ephemeris time measured in seconds past J2000. */
118 /*     STRING     O   A standard calendar representation of ET. */
119 
120 /* $ Detailed_Input */
121 
122 /*     ET       is an epoch measured in ephemeris seconds */
123 /*              past the epoch of J2000. */
124 
125 /* $ Detailed_Output */
126 
127 /*     STRING   is a calendar string representing the input ephemeris */
128 /*              epoch.  This string is based upon extending the */
129 /*              Gregorian Calendar backward and forward indefinitely */
130 /*              keeping the same rules for determining leap years. */
131 /*              Moreover, there is no accounting for leapseconds. */
132 
133 /*              To be sure that all of the date can be stored in */
134 /*              STRING, it should be declared to have length at */
135 /*              least 48 characters. */
136 
137 /*              The string will have the following format */
138 
139 /*                 year (era) mon day hr:mn:sc.sss */
140 
141 /*              Where: */
142 
143 /*                 year --- is the year */
144 /*                 era  --- is the chronological era associated with */
145 /*                          the date.  For years after 999 A.D. */
146 /*                          the era is omitted.  For years */
147 /*                          between 1 A.D. and 999 A.D. (inclusive) */
148 /*                          era is the string 'A.D.' For epochs */
149 /*                          before 1 A.D. Jan 1 00:00:00, era is */
150 /*                          given as 'B.C.' and the year is converted */
151 /*                          to years before the "Christian Era". */
152 /*                          The last B.C. epoch is */
153 
154 /*                            1 B.C. DEC 31 23:59:59.999 */
155 
156 /*                          The first A.D. epoch (which occurs .001 */
157 /*                          seconds after the last B.C. epoch) is: */
158 
159 /*                             1 A.D. JAN 1 00:00:00.000 */
160 
161 /*                          Note: there is no year 0 A.D. or 0 B.C. */
162 /*                 mon  --- is a 3-letter abbreviation for the month */
163 /*                          in all capital letters. */
164 /*                 day  --- is the day of the month */
165 /*                 hr   --- is the hour of the day (between 0 and 23) */
166 /*                          leading zeros are added to hr if the */
167 /*                          numeric value is less than 10. */
168 /*                 mn   --- is the minute of the hour (0 to 59) */
169 /*                          leading zeros are added to mn if the */
170 /*                          numeric value is less than 10. */
171 /*                 sc.sss   is the second of the minute to 3 decimal */
172 /*                          places ( 0 to 59.999).  Leading zeros */
173 /*                          are added if the numeric value is less */
174 /*                          than 10.  Seconds are truncated, not */
175 /*                          rounded. */
176 
177 
178 /* $ Parameters */
179 
180 /*     None. */
181 
182 /* $ Exceptions */
183 
184 /*     Error free. */
185 
186 /*     1) If the input ET is so large that the corresponding */
187 /*        number of days since 1 A.D. Jan 1, 00:00:00 is */
188 /*        within 1 of overflowing or underflowing an integer, */
189 /*        ET will not be converted to the correct string */
190 /*        representation rather, the string returned will */
191 /*        state that the epoch was before or after the day */
192 /*        that is INTMIN +1 or INTMAX - 1 days after */
193 /*        1 A.D. Jan 1, 00:00:00. */
194 
195 /*     2) If the output string is not sufficiently long to hold */
196 /*        the full date, it will be truncated on the right. */
197 
198 /* $ Files */
199 
200 /*     None. */
201 
202 /* $ Particulars */
203 
204 /*     This is an error free routine for converting ephemeris epochs */
205 /*     represented as seconds past the J2000 epoch to formal */
206 /*     calendar strings based upon the Gregorian Calendar.  This formal */
207 /*     time is often useful when one needs a human recognizable */
208 /*     form of an ephemeris epoch.  There is no accounting for leap */
209 /*     seconds in the output times produced. */
210 
211 /*     Note: The calendar epochs produced are not the same as the */
212 /*           UTC calendar epochs that correspond to ET. The strings */
213 /*           produced by this routine may vary from the corresponding */
214 /*           UTC epochs by more than 1 minute. */
215 
216 /*     This routine can be used in creating error messages or */
217 /*     in routines and programs in which one prefers to report */
218 /*     times without employing leapseconds to produce exact UTC */
219 /*     epochs. */
220 
221 
222 /* $ Examples */
223 
224 /*     Suppose you wish to  report that no data is */
225 /*     available at a particular ephemeris epoch ET.  The following */
226 /*     code shows how you might accomplish this task. */
227 
228 /*     CALL DPSTRF ( ET,  6, 'F', ETSTR  ) */
229 /*     CALL ETCAL  ( ET,          STRING ) */
230 
231 /*     E1 = RTRIM   (             STRING ) */
232 /*     E2 = RTRIM   (             ETSTR  ) */
233 
234 /*     WRITE (*,*) 'There is no data available for the body ' */
235 /*     WRITE (*,*) 'at requested time: ' */
236 /*     WRITE (*,*) '   ', STRING(1:E1), ' (', ETSTR(1:E2), ')' */
237 
238 
239 /* $ Restrictions */
240 
241 /*     One must keep in mind when using this routine that */
242 /*     ancient times are not based upon the Gregorian */
243 /*     calendar.  For example the 0 point of the Julian */
244 /*     Date system is 4713 B.C. Jan 1, 12:00:00 on the Julian */
245 /*     Calendar.  If one formalized the Gregorian calendar */
246 /*     and extended it indefinitely, the zero point of the Julian */
247 /*     date system corresponds to 4714 B.C. NOV 24 12:00:00 on */
248 /*     the Gregorian calendar.  There are several reasons for this. */
249 /*     Leap years in the Julian calendar occur every */
250 /*     4 years (including *all* centuries).  Moreover,  the */
251 /*     Gregorian calendar "effectively" begins on 15 Oct, 1582 A.D. */
252 /*     which is 5 Oct, 1582 A.D. in the Julian Calendar. */
253 
254 /*     Therefore you must be careful in your interpretation */
255 /*     of ancient dates produced by this routine. */
256 
257 /* $ Literature_References */
258 
259 /*     1. "From Sundial to Atomic Clocks---Understanding Time and */
260 /*         Frequency" by James Jespersen and Jane Fitz-Randolph */
261 /*         Dover Publications, Inc. New York (1982). */
262 
263 /* $ Author_and_Institution */
264 
265 /*     W.L. Taber      (JPL) */
266 /*     K.R. Gehringer  (JPL) */
267 
268 /* $ Version */
269 
270 /* -     SPICELIB Version 2.2.0, 05-MAR-1998 (WLT) */
271 
272 /*         The documentation concerning the appearance of the output */
273 /*         time string was corrected so that it does not suggest */
274 /*         a comma is inserted after the day of the month.  The */
275 /*         comma was removed from the output string in Version 2.0.0 */
276 /*         (see the note below) but the documentation was not upgraded */
277 /*         accordingly. */
278 
279 /* -     SPICELIB Version 2.1.0, 20-MAY-1996 (WLT) */
280 
281 /*         Two arrays that were initialized but never used were */
282 /*         removed. */
283 
284 /* -     SPICELIB Version 2.0.0, 16-AUG-1995 (KRG) */
285 
286 /*         If the day number was less than 10, the spacing was off for */
287 /*         the rest of the time by one space, that for the "tens" digit. */
288 /*         This has been fixed by using a leading zero when the number of */
289 /*         days is < 10. */
290 
291 /*         Also, the comma that appeared between the month/day/year */
292 /*         and the hour:minute:seconds tokens has been removed. This was */
293 /*         done in order to make the calendar date format of ETCAL */
294 /*         consistent with the calendar date format of ET2UTC. */
295 
296 
297 /* -     SPICELIB Version 1.0.0, 14-DEC-1993 (WLT) */
298 
299 /* -& */
300 /* $ Index_Entries */
301 
302 /*     Convert ephemeris time to a formal calendar date */
303 
304 /* -& */
305 /* $ Revisions */
306 
307 /* -     SPICELIB Version 2.1.0, 20-MAY-1996 (WLT) */
308 
309 /*         Two arrays that were initialized but never used were */
310 /*         removed. */
311 
312 /* -     SPICELIB Version 2.0.0, 16-AUG-1995 (KRG) */
313 
314 /*         If the day number was less than 10, the spacing was off for */
315 /*         the rest of the time by one space, that for the "tens" digit. */
316 /*         This has been fixed byusing a leading zero when the number of */
317 /*         days is < 10. */
318 
319 /*         Also, the comma that appeared between the month/day/year */
320 /*         and the hour:minute:seconds tokens has been removed. This was */
321 /*         done in order to make the calendar date format of ETCAL */
322 /*         consistent with the calendar date format of ET2UTC. */
323 
324 /* -     SPICELIB Version 1.0.0, 14-DEC-1993 (WLT) */
325 
326 /* -& */
327 
328 /*     Spicelib Functions. */
329 
330 
331 /*     We declare the variables that contain the number of days in */
332 /*     400 years, 100 years, 4 years and 1 year. */
333 
334 
335 /*     The following integers give the number of days during the */
336 /*     associated month of a non-leap year. */
337 
338 
339 /*     The integers that follow give the number of days in a normal */
340 /*     year that precede the first of the month. */
341 
342 
343 /*     The integers that follow give the number of days in a leap */
344 /*     year that precede the first of the month. */
345 
346 
347 /*     The variables below hold the components of the output string */
348 /*     before they are put together. */
349 
350 
351 /*     We will construct our string using the local variable DATE */
352 /*     and transfer the results to the output STRING when we are */
353 /*     done. */
354 
355 
356 /*     MONTHS contains 3-letter abbreviations for the months of the year */
357 
358 
359 /*     The array EXTRA contains the number of additional days that */
360 /*     appear before the first of a month during a leap year (as opposed */
361 /*     to a non-leap year). */
362 
363 
364 /*     DPJAN0(I) gives the number of days that occur before the I'th */
365 /*     month of a normal year. */
366 
367 
368 /*     Definitions of statement functions. */
369 
370 
371 /*     The number of days elapsed since Jan 1, of year 1 A.D. to */
372 /*     Jan 1 of YEAR is given by: */
373 
374 
375 /*     The number of leap days in a year is given by: */
376 
377 
378 /*     To compute the day of the year we */
379 
380 /*        look up the number of days to the beginning of the month, */
381 
382 /*        add on the number leap days that occurred prior to that */
383 /*        time */
384 
385 /*        add on the number of days into the month */
386 
387 
388 /*     The number of days since 1 Jan 1 A.D. is given by: */
389 
390     if (first) {
391 	first = FALSE_;
392 	halfd = spd_() / 2.;
393 	secspd = spd_();
394 	dn2000 = (c__2000 - 1) * 365 + (c__2000 - 1) / 4 - (c__2000 - 1) /
395 		100 + (c__2000 - 1) / 400 + (dpjan0[(i__1 = c__1 - 1) < 12 &&
396 		0 <= i__1 ? i__1 : s_rnge("dpjan0", i__1, "etcal_", (ftnlen)
397 		571)] + extra[(i__2 = c__1 - 1) < 12 && 0 <= i__2 ? i__2 :
398 		s_rnge("extra", i__2, "etcal_", (ftnlen)571)] * ((c__2000 / 4
399 		<< 2) / c__2000 - c__2000 / 100 * 100 / c__2000 + c__2000 /
400 		400 * 400 / c__2000) + c__1) - 1;
401 	dmxint = (doublereal) intmax_();
402 	dmnint = (doublereal) intmin_();
403     }
404 
405 /*     Now we "in-line" compute the following call. */
406 
407 /*        call rmaind ( et + halfd, secspd, dp2000, secs ) */
408 
409 /*     because we can't make a call to rmaind. */
410 
411 /*     The reader may wonder why we use et + halfd.  The value */
412 /*     et is seconds past the ephemeris epoch of J2000 which */
413 /*     is at 2000 Jan 1, 12:00:00.  We want to compute days past */
414 /*     2000 Jan 1, 00:00:00.  The seconds past THAT epoch is et + halfd. */
415 /*     We add on 0.0005 seconds so that the string produced will be */
416 /*     rounded to the nearest millisecond. */
417 
418     mydnom = secspd;
419     mynum = *et + halfd;
420     d__1 = mynum / mydnom;
421     q = d_int(&d__1);
422     remd = mynum - q * mydnom;
423     if (remd < 0.) {
424 	q += -1.;
425 	remd += mydnom;
426     }
427     secs = remd;
428     dp2000 = q;
429 
430 /*     Do something about the problem when ET is vastly */
431 /*     out of range.  (Day number outside MAX and MIN integer). */
432 
433     if (dp2000 + dn2000 < dmnint + 1) {
434 	dp2000 = dmnint - dn2000 + 1;
435 	s_copy(messge, "Epoch before ", (ftnlen)16, (ftnlen)13);
436 	secs = 0.;
437     } else if (dp2000 + dn2000 > dmxint - 1) {
438 	dp2000 = dmxint - dn2000 - 1;
439 	s_copy(messge, "Epoch after ", (ftnlen)16, (ftnlen)12);
440 	secs = 0.;
441     } else {
442 	s_copy(messge, " ", (ftnlen)16, (ftnlen)1);
443     }
444 
445 /*     Compute the number of days since 1 .A.D. Jan 1, 00:00:00. */
446 /*     From the tests in the previous IF-ELSE IF-ELSE block this */
447 /*     addition is guaranteed not to overflow. */
448 
449     daynum = (integer) (dp2000 + (doublereal) dn2000);
450 
451 /*     If the number of days is negative, we need to do a little */
452 /*     work so that we can represent the date in the B.C. era. */
453 /*     We add enough multiples of 400 years so that the year will */
454 /*     be positive and then we subtract off the appropriate multiple */
455 /*     of 400 years later. */
456 
457     if (daynum < 0) {
458 
459 /*        Since we can't make the call below and remain */
460 /*        error free, we compute it ourselves. */
461 
462 /*        call rmaini ( daynum, dp400y, offset, daynum ) */
463 
464 	iq = daynum / 146097;
465 	rem = daynum - iq * 146097;
466 	if (rem < 0) {
467 	    --iq;
468 	    rem += 146097;
469 	}
470 	offset = iq;
471 	daynum = rem;
472 	adjust = TRUE_;
473     } else {
474 	adjust = FALSE_;
475     }
476 
477 /*     Next we compute the year.  Divide out multiples of 400, 100 */
478 /*     4 and 1 year.  Finally combine these to get the correct */
479 /*     value for year.  (Note this is all integer arithmetic.) */
480 
481 /*     Recall that DP1Y   =    365 */
482 /*                 DP4Y   =  4*DPY    + 1 */
483 /*                 DP100Y = 25*DP4Y   - 1 */
484 /*                 DP400Y =  4*DP100Y + 1 */
485 
486     yr400 = daynum / 146097;
487     rem = daynum - yr400 * 146097;
488 /* Computing MIN */
489     i__1 = 3, i__2 = rem / 36524;
490     yr100 = min(i__1,i__2);
491     rem -= yr100 * 36524;
492 /* Computing MIN */
493     i__1 = 24, i__2 = rem / 1461;
494     yr4 = min(i__1,i__2);
495     rem -= yr4 * 1461;
496 /* Computing MIN */
497     i__1 = 3, i__2 = rem / 365;
498     yr1 = min(i__1,i__2);
499     rem -= yr1 * 365;
500     dofyr = rem + 1;
501     year = yr400 * 400 + yr100 * 100 + (yr4 << 2) + yr1 + 1;
502 
503 /*     Get the month, and day of month (depending upon whether */
504 /*     we have a leap year or not). */
505 
506     if ((year / 4 << 2) / year - year / 100 * 100 / year + year / 400 * 400 /
507 	    year == 0) {
508 	month = lstlti_(&dofyr, &c__12, dpjan0);
509 	day = dofyr - dpjan0[(i__1 = month - 1) < 12 && 0 <= i__1 ? i__1 :
510 		s_rnge("dpjan0", i__1, "etcal_", (ftnlen)698)];
511     } else {
512 	month = lstlti_(&dofyr, &c__12, dpbegl);
513 	day = dofyr - dpbegl[(i__1 = month - 1) < 12 && 0 <= i__1 ? i__1 :
514 		s_rnge("dpbegl", i__1, "etcal_", (ftnlen)701)];
515     }
516 
517 /*     If we had to adjust the year to make it positive, we now */
518 /*     need to correct it and then convert it to a B.C. year. */
519 
520     if (adjust) {
521 	year += offset * 400;
522 	year = -year + 1;
523 	s_copy(era, " B.C. ", (ftnlen)16, (ftnlen)6);
524     } else {
525 
526 /*        If the year is less than 1000, we can't just write it */
527 /*        out.  We need to add the era.  If we don't do this */
528 /*        the dates look very confusing. */
529 
530 	if (year < 1000) {
531 	    s_copy(era, " A.D. ", (ftnlen)16, (ftnlen)6);
532 	} else {
533 	    s_copy(era, " ", (ftnlen)16, (ftnlen)1);
534 	}
535     }
536 
537 /*     Convert Seconds to Hours, Minute and Seconds. */
538 /*     We work with thousandths of a second in integer arithmetic */
539 /*     so that all of the truncation work with seconds will already */
540 /*     be done.  (Note that we already know that SECS is greater than */
541 /*     or equal to zero so we'll have no problems with HOURS, MINS */
542 /*     or SECS becoming negative.) */
543 
544     tsecs = (integer) (secs * 1e3);
545     frac = secs - (doublereal) tsecs;
546     hours = tsecs / 3600000;
547     tsecs -= hours * 3600000;
548     mins = tsecs / 60000;
549     tsecs -= mins * 60000;
550     secs = (doublereal) tsecs / 1e3;
551 
552 /*     We round seconds if we can do so without getting seconds to be */
553 /*     bigger than 60. */
554 
555     if (secs + 5e-4 < 60.) {
556 	secs += 5e-4;
557     }
558 
559 /*     Finally, get the components of our date string. */
560 
561     intstr_(&year, ystr, (ftnlen)16);
562     if (day >= 10) {
563 	intstr_(&day, dstr, (ftnlen)16);
564     } else {
565 	s_copy(dstr, "0", (ftnlen)16, (ftnlen)1);
566 	intstr_(&day, dstr + 1, (ftnlen)15);
567     }
568 
569 /*     We want to zero pad the hours minutes and seconds. */
570 
571     if (hours < 10) {
572 	bh = 2;
573     } else {
574 	bh = 1;
575     }
576     if (mins < 10) {
577 	bm = 2;
578     } else {
579 	bm = 1;
580     }
581     s_copy(mstr, "00", (ftnlen)16, (ftnlen)2);
582     s_copy(hstr, "00", (ftnlen)16, (ftnlen)2);
583     s_copy(sstr, " ", (ftnlen)16, (ftnlen)1);
584 
585 /*     Now construct the string components for hours, minutes and */
586 /*     seconds. */
587 
588     secs = (integer) (secs * 1e3) / 1e3;
589     intstr_(&hours, hstr + (bh - 1), 16 - (bh - 1));
590     intstr_(&mins, mstr + (bm - 1), 16 - (bm - 1));
591     dpstrf_(&secs, &c__6, "F", sstr, (ftnlen)1, (ftnlen)16);
592 
593 /*     The form of the output for SSTR has a leading blank followed by */
594 /*     the first significant digit.  If a decimal point is in the */
595 /*     third slot, then SSTR is of the form ' x.xxxxx'  and we need */
596 /*     to insert a leading zero. */
597 
598     if (*(unsigned char *)&sstr[2] == '.') {
599 	*(unsigned char *)sstr = '0';
600     }
601 
602 /*     We don't want any leading spaces in SSTR, (HSTR and MSTR don't */
603 /*     have leading spaces by construction. */
604 
605     ljust_(sstr, sstr, (ftnlen)16, (ftnlen)16);
606 
607 /*     Now form the date string, squeeze out extra spaces and */
608 /*     left justify the whole thing. */
609 
610 /* Writing concatenation */
611     i__3[0] = 16, a__1[0] = messge;
612     i__3[1] = 16, a__1[1] = ystr;
613     i__3[2] = 16, a__1[2] = era;
614     i__3[3] = 3, a__1[3] = months + ((i__1 = month - 1) < 12 && 0 <= i__1 ?
615 	    i__1 : s_rnge("months", i__1, "etcal_", (ftnlen)810)) * 3;
616     i__3[4] = 1, a__1[4] = " ";
617     i__3[5] = 3, a__1[5] = dstr;
618     i__3[6] = 1, a__1[6] = " ";
619     i__3[7] = 2, a__1[7] = hstr;
620     i__3[8] = 1, a__1[8] = ":";
621     i__3[9] = 2, a__1[9] = mstr;
622     i__3[10] = 1, a__1[10] = ":";
623     i__3[11] = 6, a__1[11] = sstr;
624     s_cat(date, a__1, i__3, &c__12, (ftnlen)180);
625     cmprss_(" ", &c__1, date, date, (ftnlen)1, (ftnlen)180, (ftnlen)180);
626     ljust_(date, date, (ftnlen)180, (ftnlen)180);
627     s_copy(string, date, string_len, (ftnlen)180);
628     return 0;
629 } /* etcal_ */
630 
631