In article <C65tst.6xz@ra.nrl.navy.mil>, dere@cedar.nrl.navy.mil (Ken Dere)
wrote:
>
> We have data that we would like to plot as a function of a running
> calendar date where the axis will be labeled with the year and month,
> with tick marks at the first day of each month. Leap years should be
> treated properly. Somebody must know of such a routine. Any
> information would be appreciated.
There is a JULDAY program in User Library to compute astronomical Julian
days. Not being an astronomer, I converted my own Fortran programs to
compute day of the year (astronomers will probably jump on me for
perverting the meaning of Julian day) given year, month, and date, and a
similar program to compute month and date given year and Julian day (1-365
or 366). The programs are attached. No warranty is given. Improvements
and bug reports welcome.
The comments are not in standard IDL form. Sorry, still learning these
things.
Ken Bowman
PRO MNTHDT, year, julday, month, date
; This subroutine computes the month and day of the month given the
; year and the Julian day
; Variables
; date = day of the month (integer)
; julday = Julian day
; jdtab = table of Julian day number of last day of month
; 0 not leap year
; leap =
; 1 leap year
; maxyr = latest valid year for this function (3999)
; minyr = earliest valid year for this function (1753)
; month = month of the year (integer 1 to 12)
; year = year (integer between minyr and maxyr)
jdtab0 = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]
jdtab1 = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]
minyr = 1753
maxyr = 3999
;Begin
;Check validity of year
IF ((year LT minyr) OR (year GT maxyr)) THEN BEGIN
; PRINT, 'year = ',year ,' not in valid range ', minyr, maxyr
month = 0
date = 0
RETURN
ENDIF
;Determine whether leap year (1) or nonleap year (0)
IF(year MOD 400 EQ 0) THEN leap = 1 ELSE $
IF(year MOD 100 EQ 0) THEN leap = 0 ELSE $
IF(year MOD 4 EQ 0) THEN leap = 1 ELSE $
leap = 0
IF(leap EQ 0) THEN BEGIN
;Check validity of Julian day
IF ((julday LT 1) OR (julday GT jdtab0(12))) THEN BEGIN
; PRINT, 'julday = ', julday, ' not in valid range ', jdtab0(12)
month = 0
date = 0
RETURN
ENDIF
FOR month = 1, 12 DO BEGIN
IF(jdtab0(month) GE julday) THEN BEGIN
date = julday - jdtab0(month-1)
RETURN
ENDIF
ENDFOR
ENDIF ELSE BEGIN
;Check validity of Julian day
IF ((julday LT 1) OR (julday GT jdtab1(12))) THEN BEGIN
; PRINT, 'julday = ', julday, ' not in valid range ', jdtab1(12)
month = 0
date = 0
RETURN
ENDIF
FOR month = 1, 12 DO BEGIN
IF(jdtab1(month) GE julday) THEN BEGIN
date = julday - jdtab1(month-1)
RETURN
ENDIF
ENDFOR
ENDELSE
RETURN
END
FUNCTION MYJULDAY, year, month, date
; This function computes the Julian day given the year, month,
; and date
; Variables
; date = day of the month (integer)
; dmtab = table of number of days in each month
; JULDAY = Julian day
; jdtab = table of Julian day number of last day of previous month
; 0 not leap year
; leap =
; 1 leap year
; maxyr = latest valid year for this function (3999)
; minyr = earliest valid year for this function (1753)
; month = month of the year (integer 1 to 12)
; year = year (integer between minyr and maxyr)
; Begin
dmtab0 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
dmtab1 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
jdtab0 = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
jdtab1 = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
minyr = 1753
maxyr = 3999
;Check validity of year
IF ((year LT minyr) OR (year GT maxyr)) THEN BEGIN
; PRINT, 'year = ',year, ' not in valid range', minyr, maxyr
julday = 0
RETURN, julday
ENDIF
;Check validity of month
IF((month LT 1) OR (month GT 12)) THEN BEGIN
; PRINT, 'month = ', month, ' not in valid range 1, 12'
julday = 0
RETURN, julday
ENDIF
;Determine whether leap year (1) or nonleap year (0)
IF (year MOD 400 EQ 0) THEN leap = 1 $
ELSE IF (year MOD 100 EQ 0) THEN leap = 0 $
ELSE IF (year MOD 4 EQ 0) THEN leap = 1 $
ELSE leap = 0
IF(leap EQ 0) THEN BEGIN
;Check validity of date
IF((date LT 1) OR (date GT dmtab0(month-1))) THEN BEGIN
; PRINT, 'date =', date, ' not valid for month =', month
julday = 0
RETURN, julday
ENDIF
julday = jdtab0(month-1) + date
ENDIF ELSE BEGIN
;Check validity of date
IF((date LT 1) OR (date GT dmtab1(month-1))) THEN BEGIN
; PRINT, 'date =', date, ' not valid for month =', month
julday = 0
RETURN, julday
ENDIF
julday = jdtab1(month-1) + date
ENDELSE
RETURN, LONG(julday)
END
------------------------------------------------------------ ---------------
Dr. Kenneth P. Bowman 409-862-4060
Climate System Research Program 409-862-4132 fax
Department of Meteorology bowman@csrp.tamu.edu
Texas A&M University
College Station, TX 77843-3150
|