source: trunk/ToBeReviewed/CALENDRIER/caldat.pro @ 9

Last change on this file since 9 was 9, checked in by pinsard, 18 years ago

upgrade of CALENDRIER/Calendar according to cerbere.lodyc.jussieu.fr:/usr/home/smasson/SAXO_RD/ : files

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1; $Id$
2;
3; Copyright (c) 1992-2003, Research Systems, Inc.  All rights reserved.
4;       Unauthorized reproduction prohibited.
5;
6
7;+
8; NAME:
9;       CALDAT
10;
11; PURPOSE:
12;       Return the calendar date and time given julian date.
13;       This is the inverse of the function JULDAY.
14; CATEGORY:
15;       Misc.
16;
17; CALLING SEQUENCE:
18;       CALDAT, Julian, Month, Day, Year, Hour, Minute, Second
19;       See also: julday, the inverse of this function.
20;
21; INPUTS:
22;       JULIAN contains the Julian Day Number (which begins at noon) of the
23;       specified calendar date.  It should be a long integer.
24; OUTPUTS:
25;       (Trailing parameters may be omitted if not required.)
26;       MONTH:  Number of the desired month (1 = January, ..., 12 = December).
27;
28;       DAY:    Number of day of the month.
29;
30;       YEAR:   Number of the desired year.
31;
32;       HOUR:   Hour of the day
33;       Minute: Minute of the day
34;       Second: Second (and fractions) of the day.
35;
36; KEYWORD PARAMETERS:
37;
38;       NDAYSPM: for using a calendar with fixed number of days per
39;                months. defaut value of NDAYSPM=30
40;
41; COMMON BLOCKS: cm_4cal
42;
43; SIDE EFFECTS:
44;       None.
45;
46; RESTRICTIONS:
47;       Accuracy using IEEE double precision numbers is approximately
48;       1/10000th of a second.
49;
50; MODIFICATION HISTORY:
51;       Translated from "Numerical Recipies in C", by William H. Press,
52;       Brian P. Flannery, Saul A. Teukolsky, and William T. Vetterling.
53;       Cambridge University Press, 1988 (second printing).
54;
55;       DMS, July 1992.
56;       DMS, April 1996, Added HOUR, MINUTE and SECOND keyword
57;       AB, 7 December 1997, Generalized to handle array input.
58;
59;       Eric Guilyardi, June 1999
60;       Added key_work ndayspm for fixed number of days per months
61;
62;       AB, 3 January 2000, Make seconds output as DOUBLE in array output.
63;-
64;
65pro CALDAT, julian, month, day, year, hour, minute, second, NDAYSPM = ndayspm
66;------------------------------------------------------------
67@cm_4cal
68;------------------------------------------------------------
69  COMPILE_OPT idl2
70
71  ON_ERROR, 2                   ; Return to caller if errors
72
73  IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg'
74  if keyword_set(ndayspm) then key_caltype = '360d'
75  CASE key_caltype OF
76    'greg':BEGIN
77
78      nParam = N_PARAMS()
79      IF (nParam LT 1) THEN MESSAGE, 'Incorrect number of arguments.'
80
81      min_julian = -1095
82      max_julian = 1827933925
83      minn = MIN(julian, MAX = maxx)
84      IF (minn LT min_julian) OR (maxx GT max_julian) THEN MESSAGE, $
85        'Value of Julian date is out of allowed range.'
86
87      igreg = 2299161L                   ;Beginning of Gregorian calendar
88      julLong = FLOOR(julian + 0.5d)     ;Better be long
89      minJul = MIN(julLong)
90
91      IF (minJul GE igreg) THEN BEGIN ; all are Gregorian
92        jalpha = LONG(((julLong - 1867216L) - 0.25d) / 36524.25d)
93        ja = julLong + 1L + jalpha - long(0.25d * jalpha)
94      ENDIF ELSE BEGIN
95        ja = julLong
96        gregChange = WHERE(julLong ge igreg, ngreg)
97        IF (ngreg GT 0) THEN BEGIN
98          jalpha = long(((julLong[gregChange] - 1867216L) - 0.25d) / 36524.25d)
99          ja[gregChange] = julLong[gregChange] + 1L + jalpha - long(0.25d * jalpha)
100        ENDIF
101      ENDELSE
102      jalpha = -1               ; clear memory
103
104      jb = TEMPORARY(ja) + 1524L
105      jc = long(6680d + ((jb-2439870L)-122.1d0)/365.25d)
106      jd = long(365d * jc + (0.25d * jc))
107      je = long((jb - jd) / 30.6001d)
108
109      day = TEMPORARY(jb) - TEMPORARY(jd) - long(30.6001d * je)
110      month = TEMPORARY(je) - 1L
111      month = ((TEMPORARY(month) - 1L) MOD 12L) + 1L
112      year = TEMPORARY(jc) - 4715L
113      year = TEMPORARY(year) - (month GT 2)
114      year = year - (year LE 0)
115
116; see if we need to do hours, minutes, seconds
117      IF (nParam GT 4) THEN BEGIN
118        fraction = julian + 0.5d - TEMPORARY(julLong)
119        hour = floor(fraction * 24d)
120        fraction = TEMPORARY(fraction) - hour/24d
121        minute = floor(fraction*1440d)
122        second = (TEMPORARY(fraction) - minute/1440d) * 86400d
123      ENDIF
124
125; if julian is an array, reform all output to correct dimensions
126      IF (SIZE(julian, /N_DIMENSION) GT 0) THEN BEGIN
127        dimensions = SIZE(julian, /DIMENSION)
128        month = REFORM(month, dimensions)
129        day = REFORM(day, dimensions)
130        year = REFORM(year, dimensions)
131        IF (nParam GT 4) THEN BEGIN
132          hour = REFORM(hour, dimensions)
133          minute = REFORM(minute, dimensions)
134          second = REFORM(second, dimensions)
135        ENDIF
136      ENDIF
137
138    END
139    '360d':BEGIN
140
141      jul = long(julian)
142      f = (jul - floor(jul))
143      IF total(f NE 0.0) GT 0 THEN BEGIN ;Get hours, minutes, seconds.
144        hour = floor(f*24.)
145        f = f - hour / 24.d
146        minute = floor(f*1440)
147        second = (f - minute/1440.d0) * 86400.0d0
148      ENDIF ELSE BEGIN
149        hour = replicate(0L,  n_elements(julian))
150        minute = replicate(0L,  n_elements(julian))
151        second = replicate(0L,  n_elements(julian))
152      ENDELSE
153
154      IF keyword_set(ndayspm) THEN BEGIN
155        IF ndayspm EQ 1 THEN ndayspm = 30
156      ENDIF ELSE ndayspm = 30
157
158      ndayspm = long(ndayspm)
159      Z = floor(julian)
160      year = z/(12*ndayspm)+1
161      month = (z-(12*ndayspm)*(year-1))/ndayspm+1
162      day = z-(12*ndayspm)*(year-1)-ndayspm*(month-1)
163      WHILE total(day LT 1) GT 0 DO BEGIN
164        tochange = where(day LT 1)
165        month[tochange] = month[tochange]-1
166        day[tochange] = day[tochange]+ndayspm
167      ENDWHILE
168      WHILE total(month LT 1) GT 0 DO BEGIN
169        tochange = where(month LT 1)
170        year[tochange] = year[tochange]-1
171        month[tochange] = month[tochange]+12
172      ENDWHILE
173; year 0 does not exist...
174      neg = where(year LT 0)
175      IF neg[0] NE -1 THEN year[neg] = year[neg]-1
176    END
177    'noleap':BEGIN
178    END
179    ELSE:BEGIN
180      ng = report('only 3 types of calendar are accepted: greg, 360d and noleap')
181      return
182    END
183  ENDCASE
184;
185  return
186
187END
Note: See TracBrowser for help on using the repository browser.