home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / file2dat.zip / file2dat.cmd < prev   
OS/2 REXX Batch file  |  1995-12-02  |  7KB  |  223 lines

  1. /*
  2. program: file2dat.cmd
  3. type:    REXXSAA-OS/2
  4. purpose: allow transformations and calculations on date/time stamps of files.
  5. version: 1.0
  6. date:    Tue  95-10-31
  7. changed:
  8.  
  9. author:  Rick Curry
  10.  
  11. Based on "datergf" work by:
  12.          Rony G. Flatscher,
  13.          Wirtschaftsuniversität/Vienna
  14.          Rony.Flatscher@wu-wien.ac.at
  15.  
  16. usage:   FILE2DAT(argument)
  17.  
  18.          Where argument = STREAM( FileName, 'C', 'query datetime' )
  19.  
  20. remark:  This program only works for date/time values which are possible on
  21.          a DOS style machine: dates prior to 1980 (DOS beginning of time) are
  22.          not handled.  Thus 1/1/1980 is trivialized to = 722814.  Note that the
  23.          year 2000 is a leap year, thus trivializing the equation further.
  24.          Therefore this algorithm is generally OK until the year 2100 at which
  25.          time all matters will be settled religiously according to Heinlein.
  26.  
  27.          To compare the value generated by this algorithm with the REXX date
  28.          and time functions, the following relationship should hold.  Note that
  29.          the date and time stamps of the file named 'nul' is always now.
  30.          Unfortunately, the STREAM function will not return this information
  31.          for any device (such as nul), so that while the relationship
  32.          does hold, the function below can not be used to test it :( --
  33.          for testing I used the file 'c:\os2\system\swapper.dat'.
  34.  
  35.          evaluate 'now = ' Date('B')||'.'||Time('S')/86400
  36.          FILE2DAT(STREAM( 'nul', 'C', 'query datetime' )) = now
  37.  
  38. procedures:
  39.       DATE2DAYS:   calculate days based on 0000/01/01 (== 1)
  40.       TIME2FRACT:  calculate decimal fraction for time
  41.  
  42. */
  43.  
  44.  
  45. IF ARG(1) = ''|ARG(1) = '?' THEN SIGNAL usage
  46.  
  47. /* invoked as a COMMAND (from command-line) or as a FUNCTION ? */
  48. PARSE SOURCE . invocation .
  49. invocation_as_function = (invocation = "FUNCTION")
  50.  
  51. IF \invocation_as_function THEN     /* called as COMMAND or SUBROUTINE and not as a FUNCTION! */
  52. DO                                  /* only one argument-string, which has to be parsed ! */
  53.    argument1 = ARG(1)
  54.    argument1 = STRIP(argument1)     /* strip blanks */
  55.    argument1 = STRIP(argument1,,"'")/* strip ' */
  56.    argument1 = STRIP(argument1,,'"')/* strip " */
  57.    argcount = 1
  58.  
  59. END
  60. ELSE     /* invoked as a function */
  61. DO
  62.     argument1 = ARG(1)
  63.     argcount  = ARG()      /* number of arguments */
  64. END
  65.  
  66.  
  67. NUMERIC DIGITS 14          /* set precision to 14 digits after comma */
  68.  
  69. PARSE UPPER VAR argument1 date1 time1
  70.  
  71. /* check sorted dates & numbers */
  72.  
  73. date1 = parse_date(date1)
  74. time1 = parse_time(time1)
  75.  
  76. days1 = date2days(date1)
  77. fraction1 = time2fract(time1)
  78. result_file2dat = days1||SUBSTR(fraction1,2)
  79.  
  80.  
  81. IF invocation_as_function THEN   /* invoked as function, therefore return the value */
  82.    RETURN result_file2dat         /* return value */
  83.  
  84. /* invoked from the COMMAND-line or as a SUBROUTINE, both invocations must not return a value */
  85. SAY "file2dat - result:" result_file2dat       /* show result on standard output */
  86. RETURN
  87. /* end of main routine */
  88.  
  89.  
  90.  
  91. parse_date: PROCEDURE
  92.     PARSE ARG month '-' day '-' year
  93.  
  94.     RETURN year month day
  95. /* end of parse_DATE */
  96.  
  97.  
  98. /* parse & check time, return 24hour-Time (military time) */
  99. parse_TIME: PROCEDURE
  100.     PARSE ARG hours ':' minutes ':' seconds
  101.  
  102.     RETURN hours  minutes seconds
  103. /* end of parse_TIME */
  104.  
  105.  
  106.  
  107. /* calculate days based on 0000/01/01 (= 1. day == 1) */
  108. DATE2DAYS: PROCEDURE
  109.     PARSE ARG year month day
  110.  
  111.     IF year < 80 THEN year = year + 100 /* account for > 2000 */
  112.     year = year - 80                    /* Base days on 1980 */
  113.     days_1    = year * 365
  114.     days_1    = days_1 + 722813         /* Base calculations on 1-1-1980 */
  115.     leap_days = year % 4
  116.  
  117.     IF year > 0 THEN
  118.     DO
  119.        leap_days = leap_days + 1        /* account for leap year in 0000 */
  120.        leap_year = ((year // 4) = 0)    /* leap year in hand ? */
  121.        leap_days = leap_days - leap_year
  122.     END
  123.  
  124.     days_2 = date2julian(ARG(1))
  125.  
  126.     RETURN (days_1 + leap_days + days_2)
  127. /* end of DATE2DAYS */
  128.  
  129.  
  130.  
  131. /* calculate decimal fraction from time */
  132. TIME2FRACT: PROCEDURE                   /* calculate decimal value for time */
  133.     PARSE ARG hours minutes seconds
  134.  
  135.     /* hour_div = 24      =   24           */
  136.     /* min_div  = 1440    =   24 * 60      */
  137.     /* sec_div  = 86400   =   24 * 60 * 60 */
  138.  
  139.     RETURN ((hours/24) + (minutes/1440) + (seconds/86400))
  140. /* end of TIME2FRACT */
  141.  
  142.  
  143. /* calculate time from fraction */
  144. FRACT2TIME: PROCEDURE                   /* calculate time from given value */
  145.     /* hours    = 24      =   24           */
  146.     /* minutes  = 1440    =   24 * 60      */
  147.     /* seconds  = 86400   =   24 * 60 * 60 */
  148.  
  149.     tmp = arg(1) + 0.0000001            /* account for possible precision error */
  150.  
  151.     hours   = (tmp * 24) % 1
  152.     minutes = (tmp * 1440 - hours * 60) % 1
  153.     seconds = (tmp * 86400 - hours * 3600 - minutes * 60) % 1
  154.  
  155.     RETURN RIGHT(hours,2,'0')':'RIGHT(minutes,2,'0')':'RIGHT(seconds,2,'0')
  156.  
  157. /* end of FRACT2TIME */
  158.  
  159.  
  160. /* build Julian date from sorted date, result: yyyyddd */
  161. DATE2JULIAN: PROCEDURE
  162.     PARSE ARG year month day
  163.  
  164.      /* build monthdays array */
  165.      monthdays.1 = 31
  166.      monthdays.2 = 28
  167.      monthdays.3 = 31
  168.      monthdays.4 = 30
  169.      monthdays.5 = 31
  170.      monthdays.6 = 30
  171.      monthdays.7 = 31
  172.      monthdays.8 = 31
  173.      monthdays.9 = 30
  174.      monthdays.10 = 31
  175.      monthdays.11 = 30
  176.      monthdays.12 = 31
  177.  
  178.     /* is year a leap year ? */
  179.     leap_year = (year // 4) = 0         /* Julian calender    */
  180.     monthdays.2 = 28 + leap_year
  181.  
  182.     result_function = 0
  183.     DO i = 1 TO month - 1
  184.        result_function = result_function + monthdays.i
  185.     END
  186.  
  187.     result_function = result_function + day
  188.  
  189.     RETURN result_function
  190. /* end of DATE2JULIAN */
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199. USAGE:
  200. SAY
  201. SAY 'usage as a function in REXX-programs:'
  202. SAY '         FILE2DAT(argument)'
  203. SAY
  204. SAY 'usage from command-line:'
  205. SAY '         FILE2DAT argument '
  206. SAY
  207. EXIT
  208.  
  209.  
  210. ERROR:
  211. /* 1994-03-03: produce an error-message on stderr even if called as a function
  212.    /* invoked as a COMMAND (from command-line) or as a FUNCTION ? */
  213.    PARSE SOURCE . invocation .
  214.    invocation_as_function = (invocation = "FUNCTION")
  215.  
  216.    /* error message on device "STDERR", only if not called as function */
  217.    IF \invocation_as_function THEN
  218. */
  219.  
  220.       '@ECHO file2dat:' errmsg '>&2'
  221.  
  222.    EXIT ''                                      /* error, therefore return empty string */
  223.