; $Id: caldat.pro,v 1.21 2004/01/21 15:54:48 scottm Exp $ ; ; Copyright (c) 1992-2004, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ; ;+ ; NAME: ; CALDAT ; ; PURPOSE: ; Return the calendar date and time given julian date. ; This is the inverse of the function JULDAY. ; CATEGORY: ; Misc. ; ; CALLING SEQUENCE: ; CALDAT, Julian, Month, Day, Year, Hour, Minute, Second ; See also: julday, the inverse of this function. ; ; INPUTS: ; JULIAN contains the Julian Day Number (which begins at noon) of the ; specified calendar date. It should be a long integer. ; OUTPUTS: ; (Trailing parameters may be omitted if not required.) ; MONTH: Number of the desired month (1 = January, ..., 12 = December). ; ; DAY: Number of day of the month. ; ; YEAR: Number of the desired year. ; ; HOUR: Hour of the day ; Minute: Minute of the day ; Second: Second (and fractions) of the day. ; ; COMMON BLOCKS: ; None. ; ; SIDE EFFECTS: ; None. ; ; RESTRICTIONS: ; Accuracy using IEEE double precision numbers is approximately ; 1/10000th of a second. ; ; MODIFICATION HISTORY: ; Translated from "Numerical Recipies in C", by William H. Press, ; Brian P. Flannery, Saul A. Teukolsky, and William T. Vetterling. ; Cambridge University Press, 1988 (second printing). ; ; DMS, July 1992. ; DMS, April 1996, Added HOUR, MINUTE and SECOND keyword ; AB, 7 December 1997, Generalized to handle array input. ; AB, 3 January 2000, Make seconds output as DOUBLE in array output. ;- ; pro CALDAT, julian, month, day, year, hour, minute, second COMPILE_OPT idl2 ON_ERROR, 2 ; Return to caller if errors nParam = N_PARAMS() IF (nParam LT 1) THEN MESSAGE,'Incorrect number of arguments.' min_julian = -1095 max_julian = 1827933925 minn = MIN(julian, MAX=maxx) IF (minn LT min_julian) OR (maxx GT max_julian) THEN MESSAGE, $ 'Value of Julian date is out of allowed range.' igreg = 2299161L ;Beginning of Gregorian calendar julLong = FLOOR(julian + 0.5d) ;Better be long minJul = MIN(julLong) IF (minJul GE igreg) THEN BEGIN ; all are Gregorian jalpha = LONG(((julLong - 1867216L) - 0.25d) / 36524.25d) ja = julLong + 1L + jalpha - long(0.25d * jalpha) ENDIF ELSE BEGIN ja = julLong gregChange = WHERE(julLong ge igreg, ngreg) IF (ngreg GT 0) THEN BEGIN jalpha = long(((julLong[gregChange] - 1867216L) - 0.25d) / 36524.25d) ja[gregChange] = julLong[gregChange] + 1L + jalpha - long(0.25d * jalpha) ENDIF ENDELSE jalpha = -1 ; clear memory jb = TEMPORARY(ja) + 1524L jc = long(6680d + ((jb-2439870L)-122.1d0)/365.25d) jd = long(365d * jc + (0.25d * jc)) je = long((jb - jd) / 30.6001d) day = TEMPORARY(jb) - TEMPORARY(jd) - long(30.6001d * je) month = TEMPORARY(je) - 1L month = ((TEMPORARY(month) - 1L) MOD 12L) + 1L year = TEMPORARY(jc) - 4715L year = TEMPORARY(year) - (month GT 2) year = year - (year LE 0) ; see if we need to do hours, minutes, seconds IF (nParam GT 4) THEN BEGIN fraction = julian + 0.5d - TEMPORARY(julLong) hour = floor(fraction * 24d) fraction = TEMPORARY(fraction) - hour/24d minute = floor(fraction*1440d) second = (TEMPORARY(fraction) - minute/1440d) * 86400d ENDIF ; if julian is an array, reform all output to correct dimensions IF (SIZE(julian,/N_DIMENSION) GT 0) THEN BEGIN dimensions = SIZE(julian,/DIMENSION) month = REFORM(month,dimensions) day = REFORM(day,dimensions) year = REFORM(year,dimensions) IF (nParam GT 4) THEN BEGIN hour = REFORM(hour,dimensions) minute = REFORM(minute,dimensions) second = REFORM(second,dimensions) ENDIF ENDIF END