swe4r 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/swe4r/extconf.rb +3 -0
- data/ext/swe4r/src/swemptab.c +10642 -0
- data/ext/swe4r/swe4r.c +129 -0
- data/ext/swe4r/swecl.c +4948 -0
- data/ext/swe4r/swedate.c +590 -0
- data/ext/swe4r/swedate.h +82 -0
- data/ext/swe4r/swehel.c +3445 -0
- data/ext/swe4r/swehouse.c +1727 -0
- data/ext/swe4r/swehouse.h +85 -0
- data/ext/swe4r/swejpl.c +937 -0
- data/ext/swe4r/swejpl.h +105 -0
- data/ext/swe4r/swemmoon.c +1824 -0
- data/ext/swe4r/swemplan.c +959 -0
- data/ext/swe4r/swenut2000a.h +2820 -0
- data/ext/swe4r/sweodef.h +325 -0
- data/ext/swe4r/sweph.c +6241 -0
- data/ext/swe4r/sweph.h +556 -0
- data/ext/swe4r/swephexp.h +749 -0
- data/ext/swe4r/swephlib.c +2581 -0
- data/ext/swe4r/swephlib.h +177 -0
- data/lib/swe4r.rb +2 -0
- metadata +66 -0
data/ext/swe4r/swedate.c
ADDED
@@ -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
|
+
}
|
data/ext/swe4r/swedate.h
ADDED
@@ -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
|