C Program to output formatted time, with optional offset and roundoff. C C Compile: C SunOS: f77 -e -o gemtime gemtime.f C LINUX: g77 -no-underscoring -ffixed-line-lenght-none -o gemtime gemtime.f C C Usage: C gemtime [-u] [-r roundoff] [-o offset] [format] C C -u = output universal UTC (as opposed to local) time. C -r = roundoff option. This option rounds the time *down* to the C specified increment. The increment must be in the form C NNNNX, where NNNN is the number and X is the units. The C number of digits in the NNNN part is arbitrary. The units C must be either s,m,h or d for seconds, minutes, hours and C days. The default is minutes. NNNN must be a whole number. C If you need to specify a fraction, then the next smaller unit C must to used. For example, to round down to the half day, C use "-r 12h". C -o = offset option. Add the specified number of time units to the C time before output. The offset may be either positive or C negative. See the -r option for details on how to specify C the number. C [format] = output format identical to that used in the standard UNIX C command "date". However, note that the leading plus sign "+" C is not required here. See the man pages on either date(1) or C ctime(3) for further details. The default format is the C same as date "%a %h C C NOTE: The order in which the roundoff and offset are performed when both C options are requested is determined by the order of the options on C the command line C C Examples: C 1) At 14:30 UTC on 30 Nov 1994, the command: C gemtime -u -r 12h -o +2d "48h ETA forecast valid %d-%h-%y,%H%M UTC" C results in: C 48h ETA forecast valid 02-Dec-94,1200 UTC C C 2) At 14:15 one afternoon, the command: C gemtime -r 60 "Surface analysis for %H%M Local Time" C results in C Surface analysis for 1400 Local Time C C Portability: C This code has so far only been tested under SunOS. Portability to other C platforms will need to address to issues. 1) Fortan souce lines are C longer than 72 chars and 2) calls are made to standard Unix system C library routines localtime,strftime and gmtime. The Fortran compiler C must be told not to append underscores to these external names. In C Sun Fortran, this is done using the !$pragma command. Other compilers C allow this via a compile time switch. C C History: C P. Neilley, NCAR/RAP 11/94. C******************************************************************************** integer time,tm,strftime,localtime,gmtime character*200 buf character*200 args(10),offset,roundoff external time,gmtime,localtime,strftime !$pragma C(localtime,strftime,gmtime) logical utc/.false./,bad_usage/.false./,found_round/.false./,round_first/.true./ data ifmt/0/,ioff/0/,iround/1/,ioffset/0/ offset = ' ' roundoff = ' ' nargs = iargc() i = 1 do while ( i .le. nargs ) call getarg(i,args(i)) if ( args(i)(1:2) .eq. '-u' ) then utc = .true. else if ( args(i)(1:2) .eq. '-o' ) then if ( i .eq. nargs ) goto 901 i = i + 1 call getarg(i,offset) call compute_input(offset,ioffset,iret) if ( iret .ne. 0 ) goto 905 if ( .not. found_round ) round_first = .false. else if ( args(i)(1:2) .eq. '-r' ) then if ( i .eq. nargs ) goto 904 i = i + 1 call getarg(i,roundoff) if ( roundoff(1:1) .eq. '-' ) goto 901 call compute_input(roundoff,iround,iret) if ( iret .ne. 0 ) goto 906 found_round = .true. else if ( args(i)(1:1) .eq. '-' ) then goto 902 else ifmt = i end if 110 i = i + 1 end do if ( bad_usage ) goto 990 C Get the time, in secounds, roundoff and offset. isecs_current = time() if ( round_first ) then isecs_current = ( isecs_current / iround ) * iround isecs_current = isecs_current + ioffset else isecs_current = isecs_current + ioffset isecs_current = ( isecs_current / iround ) * iround end if C Convert seconds to a time array structure, tm is a pointer to that structure. if ( utc ) then tm = gmtime(isecs_current) else tm = localtime(isecs_current) end if C Format it accordingly if ( ifmt .eq. 0 ) then ifmt = 1 args(ifmt) = '%a %h %e %T %Z %Y' end if call getlen(args(ifmt),l) n = strftime(buf,%val(80),args(ifmt)(1:l)//char(0),%val(tm)) print *,buf(1:n) goto 990 901 write(0,*) '-o option requires offset specification.' goto 990 902 write(0,*) 'Unknown option:',args(i) bad_usage = .true. goto 110 903 write(0,*) 'Missing format specifier arguement.' goto 990 904 write(0,*) '-r option requires roundoff specification.' goto 990 905 write(0,*) 'Bad offset time specification.' goto 990 906 write(0,*) 'Bad roundoff time specification.' goto 990 990 continue end C******************************************************************** C Decodes input time string in format NNNNNNNX, where NNN.. is any C number and X is a units, either s,m,h,d for secs, mins, hours, days. C Returns ival in seconds. IRET is non-zero on failure. subroutine compute_input(str,ival,iret) character*(*) str character*1 units iret = -1 call getlen(str,i) if ( i .le. 0 ) return if ( (str(i:i).ge.'0') .and. (str(i:i).le.'9') ) then units = 'm' else units = str(i:i) i = i - 1 if ( i .le. 0 ) return end if read(str(:i),*,err=990) number if ( units .eq. 's' ) then ival = number else if ( units .eq. 'm' ) then ival = number * 60 else if ( units .eq. 'h' ) then ival = number * 60*60 else if ( units .eq. 'd' ) then ival = number * 60*60*24 else write(0,*) 'Illegal time units specification:',units return end if iret = 0 990 continue return end C*********************************************************** C Determine last printable character in string. subroutine getlen(str,l) character*(*) str l=len(str) do while ( (l.ge.0) .and. (str(l:l).le.' ') ) l = l - 1 end do return end