swe4r 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,590 @@
1
+ /*********************************************************
2
+ $Header: /home/dieter/sweph/RCS/swedate.c,v 1.75 2009/04/08 07:17:29 dieter Exp $
3
+ version 15-feb-89 16:30
4
+
5
+ swe_date_conversion()
6
+ swe_revjul()
7
+ swe_julday()
8
+
9
+ ************************************************************/
10
+ /* Copyright (C) 1997 - 2008 Astrodienst AG, Switzerland. All rights reserved.
11
+
12
+ License conditions
13
+ ------------------
14
+
15
+ This file is part of Swiss Ephemeris.
16
+
17
+ Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
18
+ or distributor accepts any responsibility for the consequences of using it,
19
+ or for whether it serves any particular purpose or works at all, unless he
20
+ or she says so in writing.
21
+
22
+ Swiss Ephemeris is made available by its authors under a dual licensing
23
+ system. The software developer, who uses any part of Swiss Ephemeris
24
+ in his or her software, must choose between one of the two license models,
25
+ which are
26
+ a) GNU public license version 2 or later
27
+ b) Swiss Ephemeris Professional License
28
+
29
+ The choice must be made before the software developer distributes software
30
+ containing parts of Swiss Ephemeris to others, and before any public
31
+ service using the developed software is activated.
32
+
33
+ If the developer choses the GNU GPL software license, he or she must fulfill
34
+ the conditions of that license, which includes the obligation to place his
35
+ or her whole software project under the GNU GPL or a compatible license.
36
+ See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
37
+
38
+ If the developer choses the Swiss Ephemeris Professional license,
39
+ he must follow the instructions as found in http://www.astro.com/swisseph/
40
+ and purchase the Swiss Ephemeris Professional Edition from Astrodienst
41
+ and sign the corresponding license contract.
42
+
43
+ The License grants you the right to use, copy, modify and redistribute
44
+ Swiss Ephemeris, but only under certain conditions described in the License.
45
+ Among other things, the License requires that the copyright notices and
46
+ this notice be preserved on all copies.
47
+
48
+ Authors of the Swiss Ephemeris: Dieter Koch and Alois Treindl
49
+
50
+ The authors of Swiss Ephemeris have no control or influence over any of
51
+ the derived works, i.e. over software or services created by other
52
+ programmers which use Swiss Ephemeris functions.
53
+
54
+ The names of the authors or of the copyright holder (Astrodienst) must not
55
+ be used for promoting any software, product or service which uses or contains
56
+ the Swiss Ephemeris. This copyright notice is the ONLY place where the
57
+ names of the authors can legally appear, except in cases where they have
58
+ given special permission in writing.
59
+
60
+ The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
61
+ for promoting such software, products or services.
62
+ */
63
+
64
+ /*
65
+ swe_date_conversion():
66
+ This function converts some date+time input {d,m,y,uttime}
67
+ into the Julian day number tjd.
68
+ The function checks that the input is a legal combination
69
+ of dates; for illegal dates like 32 January 1993 it returns ERR
70
+ but still converts the date correctly, i.e. like 1 Feb 1993.
71
+ The function is usually used to convert user input of birth data
72
+ into the Julian day number. Illegal dates should be notified to the user.
73
+
74
+ Be aware that we always use astronomical year numbering for the years
75
+ before Christ, not the historical year numbering.
76
+ Astronomical years are done with negative numbers, historical
77
+ years with indicators BC or BCE (before common era).
78
+ Year 0 (astronomical) = 1 BC historical.
79
+ year -1 (astronomical) = 2 BC
80
+ etc.
81
+ Many users of Astro programs do not know about this difference.
82
+
83
+ Return: OK or ERR (for illegal date)
84
+ *********************************************************/
85
+
86
+ # include "swephexp.h"
87
+ # include "sweph.h"
88
+
89
+ static AS_BOOL init_leapseconds_done = FALSE;
90
+
91
+
92
+ int FAR PASCAL_CONV swe_date_conversion(int y,
93
+ int m,
94
+ int d, /* day, month, year */
95
+ double uttime, /* UT in hours (decimal) */
96
+ char c, /* calendar g[regorian]|j[ulian] */
97
+ double *tjd)
98
+ {
99
+ int rday, rmon, ryear;
100
+ double rut, jd;
101
+ int gregflag = SE_JUL_CAL;
102
+ if (c == 'g')
103
+ gregflag = SE_GREG_CAL;
104
+ rut = uttime; /* hours UT */
105
+ jd = swe_julday(y, m, d, rut, gregflag);
106
+ swe_revjul(jd, gregflag, &ryear, &rmon, &rday, &rut);
107
+ *tjd = jd;
108
+ if (rmon == m && rday == d && ryear == y) {
109
+ return OK;
110
+ } else {
111
+ return ERR;
112
+ }
113
+ } /* end date_conversion */
114
+
115
+ /*************** swe_julday ********************************************
116
+ * This function returns the absolute Julian day number (JD)
117
+ * for a given calendar date.
118
+ * The arguments are a calendar date: day, month, year as integers,
119
+ * hour as double with decimal fraction.
120
+ * If gregflag = SE_GREG_CAL (1), Gregorian calendar is assumed,
121
+ * if gregflag = SE_JUL_CAL (0),Julian calendar is assumed.
122
+
123
+ The Julian day number is system of numbering all days continously
124
+ within the time range of known human history. It should be familiar
125
+ for every astrological or astronomical programmer. The time variable
126
+ in astronomical theories is usually expressed in Julian days or
127
+ Julian centuries (36525 days per century) relative to some start day;
128
+ the start day is called 'the epoch'.
129
+ The Julian day number is a double representing the number of
130
+ days since JD = 0.0 on 1 Jan -4712, 12:00 noon.
131
+
132
+ Midnight has always a JD with fraction .5, because traditionally
133
+ the astronomical day started at noon. This was practical because
134
+ then there was no change of date during a night at the telescope.
135
+ From this comes also the fact the noon ephemerides were printed
136
+ before midnight ephemerides were introduced early in the 20th century.
137
+
138
+ NOTE: The Julian day number must not be confused with the Julian
139
+ calendar system.
140
+ The Julian day number was introduced by Josephus Justus Scaliger
141
+ in 1583 and named either after the Julian calendar year or
142
+ after his father Julius Caesar Scaliger.
143
+
144
+ Be aware the we always use astronomical year numbering for the years
145
+ before Christ, not the historical year numbering.
146
+ Astronomical years are done with negative numbers, historical
147
+ years with indicators BC or BCE (before common era).
148
+ Year 0 (astronomical) = 1 BC
149
+ year -1 (astronomical) = 2 BC
150
+ etc.
151
+
152
+ Original author: Marc Pottenger, Los Angeles.
153
+ with bug fix for year < -4711 15-aug-88 by Alois Treindl
154
+ (The parameter sequence m,d,y still indicates the US origin,
155
+ be careful because the similar function date_conversion() uses
156
+ other parameter sequence and also Astrodienst relative juldate.)
157
+
158
+ References: Oliver Montenbruck, Grundlagen der Ephemeridenrechnung,
159
+ Verlag Sterne und Weltraum (1987), p.49 ff
160
+
161
+ related functions: swe_revjul() reverse Julian day number: compute the
162
+ calendar date from a given JD
163
+ date_conversion() includes test for legal date values
164
+ and notifies errors like 32 January.
165
+ ****************************************************************/
166
+
167
+ double FAR PASCAL_CONV swe_julday(int year, int month, int day, double hour, int gregflag)
168
+ {
169
+ double jd;
170
+ double u,u0,u1,u2;
171
+ u = year;
172
+ if (month < 3) u -=1;
173
+ u0 = u + 4712.0;
174
+ u1 = month + 1.0;
175
+ if (u1 < 4) u1 += 12.0;
176
+ jd = floor(u0*365.25)
177
+ + floor(30.6*u1+0.000001)
178
+ + day + hour/24.0 - 63.5;
179
+ if (gregflag == SE_GREG_CAL) {
180
+ u2 = floor(fabs(u) / 100) - floor(fabs(u) / 400);
181
+ if (u < 0.0) u2 = -u2;
182
+ jd = jd - u2 + 2;
183
+ if ((u < 0.0) && (u/100 == floor(u/100)) && (u/400 != floor(u/400)))
184
+ jd -=1;
185
+ }
186
+ return jd;
187
+ }
188
+
189
+ /*** swe_revjul ******************************************************
190
+ swe_revjul() is the inverse function to swe_julday(), see the description
191
+ there.
192
+ Arguments are julian day number, calendar flag (0=julian, 1=gregorian)
193
+ return values are the calendar day, month, year and the hour of
194
+ the day with decimal fraction (0 .. 23.999999).
195
+
196
+ Be aware the we use astronomical year numbering for the years
197
+ before Christ, not the historical year numbering.
198
+ Astronomical years are done with negative numbers, historical
199
+ years with indicators BC or BCE (before common era).
200
+ Year 0 (astronomical) = 1 BC historical year
201
+ year -1 (astronomical) = 2 BC historical year
202
+ year -234 (astronomical) = 235 BC historical year
203
+ etc.
204
+
205
+ Original author Mark Pottenger, Los Angeles.
206
+ with bug fix for year < -4711 16-aug-88 Alois Treindl
207
+ *************************************************************************/
208
+ void FAR PASCAL_CONV swe_revjul (double jd, int gregflag,
209
+ int *jyear, int *jmon, int *jday, double *jut)
210
+ {
211
+ double u0,u1,u2,u3,u4;
212
+ u0 = jd + 32082.5;
213
+ if (gregflag == SE_GREG_CAL) {
214
+ u1 = u0 + floor (u0/36525.0) - floor (u0/146100.0) - 38.0;
215
+ if (jd >= 1830691.5) u1 +=1;
216
+ u0 = u0 + floor (u1/36525.0) - floor (u1/146100.0) - 38.0;
217
+ }
218
+ u2 = floor (u0 + 123.0);
219
+ u3 = floor ( (u2 - 122.2) / 365.25);
220
+ u4 = floor ( (u2 - floor (365.25 * u3) ) / 30.6001);
221
+ *jmon = (int) (u4 - 1.0);
222
+ if (*jmon > 12) *jmon -= 12;
223
+ *jday = (int) (u2 - floor (365.25 * u3) - floor (30.6001 * u4));
224
+ *jyear = (int) (u3 + floor ( (u4 - 2.0) / 12.0) - 4800);
225
+ *jut = (jd - floor (jd + 0.5) + 0.5) * 24.0;
226
+ }
227
+
228
+ /* transform local time to UTC or UTC to local time
229
+ *
230
+ * input
231
+ * iyear ... dsec date and time
232
+ * d_timezone timezone offset
233
+ * output
234
+ * iyear_out ... dsec_out
235
+ *
236
+ * For time zones east of Greenwich, d_timezone is positive.
237
+ * For time zones west of Greenwich, d_timezone is negative.
238
+ *
239
+ * For conversion from local time to utc, use +d_timezone.
240
+ * For conversion from utc to local time, use -d_timezone.
241
+ */
242
+ void FAR PASCAL_CONV swe_utc_time_zone(
243
+ int32 iyear, int32 imonth, int32 iday,
244
+ int32 ihour, int32 imin, double dsec,
245
+ double d_timezone,
246
+ int32 *iyear_out, int32 *imonth_out, int32 *iday_out,
247
+ int32 *ihour_out, int32 *imin_out, double *dsec_out
248
+ )
249
+ {
250
+ double tjd, d;
251
+ AS_BOOL have_leapsec = FALSE;
252
+ double dhour;
253
+ if (dsec >= 60.0) {
254
+ have_leapsec = TRUE;
255
+ dsec -= 1.0;
256
+ }
257
+ dhour = ((double) ihour) + ((double) imin) / 60.0 + dsec / 3600.0;
258
+ tjd = swe_julday(iyear, imonth, iday, 0, SE_GREG_CAL);
259
+ dhour -= d_timezone;
260
+ if (dhour < 0.0) {
261
+ tjd -= 1.0;
262
+ dhour += 24.0;
263
+ }
264
+ if (dhour >= 24.0) {
265
+ tjd += 1.0;
266
+ dhour -= 24.0;
267
+ }
268
+ swe_revjul(tjd + 0.001, SE_GREG_CAL, iyear_out, imonth_out, iday_out, &d);
269
+ *ihour_out = (int) dhour;
270
+ d = (dhour - (double) *ihour_out) * 60;
271
+ *imin_out = (int) d;
272
+ *dsec_out = (d - (double) *imin_out) * 60;
273
+ if (have_leapsec)
274
+ *dsec_out += 1.0;
275
+ }
276
+
277
+ /*
278
+ * functions for the handling of UTC
279
+ */
280
+
281
+ /* Leap seconds were inserted at the end of the following days:*/
282
+ #define NLEAP_SECONDS 24
283
+ #define NLEAP_SECONDS_SPACE 100
284
+ static int leap_seconds[NLEAP_SECONDS_SPACE] = {
285
+ 19720630,
286
+ 19721231,
287
+ 19731231,
288
+ 19741231,
289
+ 19751231,
290
+ 19761231,
291
+ 19771231,
292
+ 19781231,
293
+ 19791231,
294
+ 19810630,
295
+ 19820630,
296
+ 19830630,
297
+ 19850630,
298
+ 19871231,
299
+ 19891231,
300
+ 19901231,
301
+ 19920630,
302
+ 19930630,
303
+ 19940630,
304
+ 19951231,
305
+ 19970630,
306
+ 19981231,
307
+ 20051231,
308
+ 20081231,
309
+ 0 /* keep this 0 as end mark */
310
+ };
311
+ #define J1972 2441317.5
312
+ #define NLEAP_INIT 10
313
+
314
+ /* Read additional leap second dates from external file, if given.
315
+ */
316
+ static int init_leapsec(void)
317
+ {
318
+ FILE *fp;
319
+ int ndat, ndat_last;
320
+ int tabsiz = 0;
321
+ int i;
322
+ char s[AS_MAXCH];
323
+ char *sp;
324
+ if (!init_leapseconds_done) {
325
+ init_leapseconds_done = TRUE;
326
+ tabsiz = NLEAP_SECONDS;
327
+ ndat_last = leap_seconds[NLEAP_SECONDS - 1];
328
+ /* no error message if file is missing */
329
+ if ((fp = swi_fopen(-1, "seleapsec.txt", swed.ephepath, NULL)) == NULL)
330
+ return NLEAP_SECONDS;
331
+ while(fgets(s, AS_MAXCH, fp) != NULL) {
332
+ sp = s;
333
+ while (*sp == ' ' || *sp == '\t') sp++;
334
+ sp++;
335
+ if (*sp == '#' || *sp == '\n')
336
+ continue;
337
+ ndat = atoi(s);
338
+ if (ndat <= ndat_last)
339
+ continue;
340
+ /* table space is limited. no error msg, if exceeded */
341
+ if (tabsiz >= NLEAP_SECONDS_SPACE)
342
+ return tabsiz;
343
+ leap_seconds[tabsiz] = ndat;
344
+ tabsiz++;
345
+ }
346
+ if (tabsiz > NLEAP_SECONDS) leap_seconds[tabsiz] = 0; /* end mark */
347
+ fclose(fp);
348
+ return tabsiz;
349
+ }
350
+ /* find table size */
351
+ tabsiz = 0;
352
+ for (i = 0; i < NLEAP_SECONDS_SPACE; i++) {
353
+ if (leap_seconds[i] == 0)
354
+ break;
355
+ else
356
+ tabsiz++;
357
+ }
358
+ return tabsiz;
359
+ }
360
+
361
+ /*
362
+ * Input: Clock time UTC, year, month, day, hour, minute, second (decimal).
363
+ * gregflag Calendar flag
364
+ * serr error string
365
+ * Output: An array of doubles:
366
+ * dret[0] = Julian day number TT (ET)
367
+ * dret[1] = Julian day number UT1
368
+ *
369
+ * Function returns OK or Error.
370
+ *
371
+ * - Before 1972, swe_utc_to_jd() treats its input time as UT1.
372
+ * Note: UTC was introduced in 1961. From 1961 - 1971, the length of the
373
+ * UTC second was regularly changed, so that UTC remained very close to UT1.
374
+ * - From 1972 on, input time is treated as UTC.
375
+ * - If delta_t - nleap - 32.184 > 1, the input time is treated as UT1.
376
+ * Note: Like this we avoid errors greater than 1 second in case that
377
+ * the leap seconds table (or the Swiss Ephemeris version) is not updated
378
+ * for a long time.
379
+ */
380
+ int32 FAR PASCAL_CONV swe_utc_to_jd(int32 iyear, int32 imonth, int32 iday, int32 ihour, int32 imin, double dsec, int32 gregflag, double *dret, char *serr)
381
+ {
382
+ double tjd_ut1, tjd_et, tjd_et_1972, dhour, d;
383
+ int iyear2, imonth2, iday2;
384
+ int i, j, ndat, nleap, tabsiz_nleap;
385
+ /*
386
+ * error handling: invalid iyear etc.
387
+ */
388
+ tjd_ut1 = swe_julday(iyear, imonth, iday, 0, gregflag);
389
+ swe_revjul(tjd_ut1, gregflag, &iyear2, &imonth2, &iday2, &d);
390
+ if (iyear != iyear2 || imonth != imonth2 || iday != iday2) {
391
+ if (serr != NULL)
392
+ sprintf(serr, "invalid date: year = %d, month = %d, day = %d", iyear, imonth, iday);
393
+ return ERR;
394
+ }
395
+ if (ihour < 0 || ihour > 23
396
+ || imin < 0 || imin > 59
397
+ || dsec < 0 || dsec >= 61
398
+ || (dsec >= 60 && (imin < 59 || ihour < 23 || tjd_ut1 < J1972))) {
399
+ if (serr != NULL)
400
+ sprintf(serr, "invalid time: %d:%d:%.2f", ihour, imin, dsec);
401
+ return ERR;
402
+ }
403
+ dhour = (double) ihour + ((double) imin) / 60.0 + dsec / 3600.0;
404
+ /*
405
+ * before 1972, we treat input date as UT1
406
+ */
407
+ if (tjd_ut1 < J1972) {
408
+ dret[1] = swe_julday(iyear, imonth, iday, dhour, gregflag);
409
+ dret[0] = dret[1] + swe_deltat(dret[1]);
410
+ return OK;
411
+ }
412
+ /*
413
+ * if gregflag = Julian calendar, convert to gregorian calendar
414
+ */
415
+ if (gregflag == SE_JUL_CAL) {
416
+ gregflag = SE_GREG_CAL;
417
+ swe_revjul(tjd_ut1, gregflag, &iyear, &imonth, &iday, &d);
418
+ }
419
+ /*
420
+ * number of leap seconds since 1972:
421
+ */
422
+ tabsiz_nleap = init_leapsec();
423
+ nleap = NLEAP_INIT; /* initial difference between UTC and TAI in 1972 */
424
+ ndat = iyear * 10000 + imonth * 100 + iday;
425
+ for (i = 0; i < tabsiz_nleap; i++) {
426
+ if (ndat <= leap_seconds[i])
427
+ break;
428
+ nleap++;
429
+ }
430
+ /*
431
+ * For input dates > today:
432
+ * If leap seconds table is not up to date, we'd better interpret the
433
+ * input time as UT1, not as UTC. How do we find out?
434
+ * Check, if delta_t - nleap - 32.184 > 0.9
435
+ */
436
+ d = swe_deltat(tjd_ut1) * 86400.0;
437
+ if (d - (double) nleap - 32.184 >= 1.0) {
438
+ dret[1] = tjd_ut1 + dhour / 24.0;
439
+ dret[0] = dret[1] + swe_deltat(dret[1]);
440
+ return OK;
441
+ }
442
+ /*
443
+ * if input second is 60: is it a valid leap second ?
444
+ */
445
+ if (dsec >= 60) {
446
+ j = 0;
447
+ for (i = 0; i < tabsiz_nleap; i++) {
448
+ if (ndat == leap_seconds[i]) {
449
+ j = 1;
450
+ break;
451
+ }
452
+ }
453
+ if (j != 1) {
454
+ if (serr != NULL)
455
+ sprintf(serr, "invalid time (no leap second!): %d:%d:%.2f", ihour, imin, dsec);
456
+ return ERR;
457
+ }
458
+ }
459
+ /*
460
+ * convert UTC to ET and UT1
461
+ */
462
+ /* the number of days between input date and 1 jan 1972: */
463
+ d = tjd_ut1 - J1972;
464
+ /* SI time since 1972, ignoring leap seconds: */
465
+ d += (double) ihour / 24.0 + (double) imin / 1440.0 + dsec / 86400.0;
466
+ /* ET (TT) */
467
+ tjd_et_1972 = J1972 + (32.184 + NLEAP_INIT) / 86400.0;
468
+ tjd_et = tjd_et_1972 + d + ((double) (nleap - NLEAP_INIT)) / 86400.0;
469
+ d = swe_deltat(tjd_et);
470
+ tjd_ut1 = tjd_et - swe_deltat(tjd_et - d);
471
+ dret[0] = tjd_et;
472
+ dret[1] = tjd_ut1;
473
+ return OK;
474
+ }
475
+
476
+ /*
477
+ * Input: tjd_et Julian day number, terrestrial time (ephemeris time).
478
+ * gregfalg Calendar flag
479
+ * Output: UTC year, month, day, hour, minute, second (decimal).
480
+ *
481
+ * - Before 1 jan 1972 UTC, output UT1.
482
+ * Note: UTC was introduced in 1961. From 1961 - 1971, the length of the
483
+ * UTC second was regularly changed, so that UTC remained very close to UT1.
484
+ * - From 1972 on, output is UTC.
485
+ * - If delta_t - nleap - 32.184 > 1, the output is UT1.
486
+ * Note: Like this we avoid errors greater than 1 second in case that
487
+ * the leap seconds table (or the Swiss Ephemeris version) has not been
488
+ * updated for a long time.
489
+ */
490
+ void FAR PASCAL_CONV swe_jdet_to_utc(double tjd_et, int32 gregflag, int32 *iyear, int32 *imonth, int32 *iday, int32 *ihour, int32 *imin, double *dsec)
491
+ {
492
+ int i;
493
+ int second_60 = 0;
494
+ int iyear2, imonth2, iday2, nleap, ndat, tabsiz_nleap;
495
+ double d, tjd, tjd_et_1972, tjd_ut, dret[10];
496
+ /*
497
+ * if tjd_et is before 1 jan 1972 UTC, return UT1
498
+ */
499
+ tjd_et_1972 = J1972 + (32.184 + NLEAP_INIT) / 86400.0;
500
+ d = swe_deltat(tjd_et);
501
+ tjd_ut = tjd_et - swe_deltat(tjd_et - d);
502
+ if (tjd_et < tjd_et_1972) {
503
+ swe_revjul(tjd_ut, gregflag, iyear, imonth, iday, &d);
504
+ *ihour = (int32) d;
505
+ d -= (double) *ihour;
506
+ d *= 60;
507
+ *imin = (int32) d;
508
+ *dsec = (d - (double) *imin) * 60.0;
509
+ return;
510
+ }
511
+ /*
512
+ * minimum number of leap seconds since 1972; we may be missing one leap
513
+ * second
514
+ */
515
+ tabsiz_nleap = init_leapsec();
516
+ swe_revjul(tjd_ut-1, SE_GREG_CAL, &iyear2, &imonth2, &iday2, &d);
517
+ ndat = iyear2 * 10000 + imonth2 * 100 + iday2;
518
+ nleap = 0;
519
+ for (i = 0; i < tabsiz_nleap; i++) {
520
+ if (ndat <= leap_seconds[i])
521
+ break;
522
+ nleap++;
523
+ }
524
+ /* date of potentially missing leapsecond */
525
+ if (nleap < tabsiz_nleap) {
526
+ i = leap_seconds[nleap];
527
+ iyear2 = i / 10000;
528
+ imonth2 = (i % 10000) / 100;;
529
+ iday2 = i % 100;
530
+ tjd = swe_julday(iyear2, imonth2, iday2, 0, SE_GREG_CAL);
531
+ swe_revjul(tjd+1, SE_GREG_CAL, &iyear2, &imonth2, &iday2, &d);
532
+ swe_utc_to_jd(iyear2,imonth2,iday2, 0, 0, 0, SE_GREG_CAL, dret, NULL);
533
+ d = tjd_et - dret[0];
534
+ if (d >= 0) {
535
+ nleap++;
536
+ } else if (d < 0 && d > -1.0/86400.0) {
537
+ second_60 = 1;
538
+ }
539
+ }
540
+ /*
541
+ * UTC, still unsure about one leap second
542
+ */
543
+ tjd = J1972 + (tjd_et - tjd_et_1972) - ((double) nleap + second_60) / 86400.0;
544
+ swe_revjul(tjd, SE_GREG_CAL, iyear, imonth, iday, &d);
545
+ *ihour = (int32) d;
546
+ d -= (double) *ihour;
547
+ d *= 60;
548
+ *imin = (int32) d;
549
+ *dsec = (d - (double) *imin) * 60.0 + second_60;
550
+ /*
551
+ * For input dates > today:
552
+ * If leap seconds table is not up to date, we'd better interpret the
553
+ * input time as UT1, not as UTC. How do we find out?
554
+ * Check, if delta_t - nleap - 32.184 > 0.9
555
+ */
556
+ d = swe_deltat(tjd_et);
557
+ d = swe_deltat(tjd_et - d);
558
+ if (d * 86400.0 - (double) (nleap + NLEAP_INIT) - 32.184 >= 1.0) {
559
+ swe_revjul(tjd_et - d, SE_GREG_CAL, iyear, imonth, iday, &d);
560
+ *ihour = (int32) d;
561
+ d -= (double) *ihour;
562
+ d *= 60;
563
+ *imin = (int32) d;
564
+ *dsec = (d - (double) *imin) * 60.0;
565
+ }
566
+ if (gregflag == SE_JUL_CAL) {
567
+ tjd = swe_julday(*iyear, *imonth, *iday, 0, SE_GREG_CAL);
568
+ swe_revjul(tjd, gregflag, iyear, imonth, iday, &d);
569
+ }
570
+ }
571
+
572
+ /*
573
+ * Input: tjd_ut Julian day number, universal time (UT1).
574
+ * gregfalg Calendar flag
575
+ * Output: UTC year, month, day, hour, minute, second (decimal).
576
+ *
577
+ * - Before 1 jan 1972 UTC, output UT1.
578
+ * Note: UTC was introduced in 1961. From 1961 - 1971, the length of the
579
+ * UTC second was regularly changed, so that UTC remained very close to UT1.
580
+ * - From 1972 on, output is UTC.
581
+ * - If delta_t - nleap - 32.184 > 1, the output is UT1.
582
+ * Note: Like this we avoid errors greater than 1 second in case that
583
+ * the leap seconds table (or the Swiss Ephemeris version) has not been
584
+ * updated for a long time.
585
+ */
586
+ void FAR PASCAL_CONV swe_jdut1_to_utc(double tjd_ut, int32 gregflag, int32 *iyear, int32 *imonth, int32 *iday, int32 *ihour, int32 *imin, double *dsec)
587
+ {
588
+ double tjd_et = tjd_ut + swe_deltat(tjd_ut);
589
+ swe_jdet_to_utc(tjd_et, gregflag, iyear, imonth, iday, ihour, imin, dsec);
590
+ }
@@ -0,0 +1,82 @@
1
+ /*********************************************************
2
+ $Header: /home/dieter/sweph/RCS/swedate.h,v 1.74 2008/06/16 10:07:20 dieter Exp $
3
+ version 15-feb-89 16:30
4
+ *********************************************************/
5
+
6
+ /* Copyright (C) 1997 - 2008 Astrodienst AG, Switzerland. All rights reserved.
7
+
8
+ License conditions
9
+ ------------------
10
+
11
+ This file is part of Swiss Ephemeris.
12
+
13
+ Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
14
+ or distributor accepts any responsibility for the consequences of using it,
15
+ or for whether it serves any particular purpose or works at all, unless he
16
+ or she says so in writing.
17
+
18
+ Swiss Ephemeris is made available by its authors under a dual licensing
19
+ system. The software developer, who uses any part of Swiss Ephemeris
20
+ in his or her software, must choose between one of the two license models,
21
+ which are
22
+ a) GNU public license version 2 or later
23
+ b) Swiss Ephemeris Professional License
24
+
25
+ The choice must be made before the software developer distributes software
26
+ containing parts of Swiss Ephemeris to others, and before any public
27
+ service using the developed software is activated.
28
+
29
+ If the developer choses the GNU GPL software license, he or she must fulfill
30
+ the conditions of that license, which includes the obligation to place his
31
+ or her whole software project under the GNU GPL or a compatible license.
32
+ See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
33
+
34
+ If the developer choses the Swiss Ephemeris Professional license,
35
+ he must follow the instructions as found in http://www.astro.com/swisseph/
36
+ and purchase the Swiss Ephemeris Professional Edition from Astrodienst
37
+ and sign the corresponding license contract.
38
+
39
+ The License grants you the right to use, copy, modify and redistribute
40
+ Swiss Ephemeris, but only under certain conditions described in the License.
41
+ Among other things, the License requires that the copyright notices and
42
+ this notice be preserved on all copies.
43
+
44
+ Authors of the Swiss Ephemeris: Dieter Koch and Alois Treindl
45
+
46
+ The authors of Swiss Ephemeris have no control or influence over any of
47
+ the derived works, i.e. over software or services created by other
48
+ programmers which use Swiss Ephemeris functions.
49
+
50
+ The names of the authors or of the copyright holder (Astrodienst) must not
51
+ be used for promoting any software, product or service which uses or contains
52
+ the Swiss Ephemeris. This copyright notice is the ONLY place where the
53
+ names of the authors can legally appear, except in cases where they have
54
+ given special permission in writing.
55
+
56
+ The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
57
+ for promoting such software, products or services.
58
+ */
59
+
60
+ #ifdef __cplusplus
61
+ extern "C" {
62
+ #endif
63
+
64
+ #ifndef _SWEDLL_H
65
+ extern EXP32 int FAR PASCAL_CONV EXP16 swe_date_conversion (
66
+ int y , int m , int d , /* year, month, day */
67
+ double utime, /* universal time in hours (decimal) */
68
+ char c, /* calendar g[regorian]|j[ulian]|a[stro = greg] */
69
+ double *tgmt);
70
+
71
+ extern EXP32 double *FAR PASCAL_CONV EXP16 swe_julday(
72
+ int year, int month, int day, double hour,
73
+ int gregflag);
74
+
75
+ extern EXP32 void FAR PASCAL_CONV EXP16 swe_revjul (
76
+ double jd,
77
+ int gregflag,
78
+ int *jyear, int *jmon, int *jday, double *jut);
79
+ #endif
80
+ #ifdef __cplusplus
81
+ } /* extern C */
82
+ #endif