home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PTOOLBBS.ZIP / PTOOLBBS.BOX
Encoding:
Text File  |  1986-01-08  |  35.7 KB  |  929 lines

  1. { PTOOL1.BOX     Copyright 1985  R D Ostrander                   Version 1.0
  2.                                  Ostrander Data Services
  3.                                  5437 Honey Manor Dr
  4.                                  Indianapolis  IN  46241
  5.  
  6.  
  7.   PTOOLDAT portion of PTOOL1.BOX begins here ****************************** 
  8.  
  9.   Constants and Parameters Begin Here ************************************* }
  10.  
  11.  
  12. TYPE
  13.  
  14.      PTOOLDAT_Str_21   = String [21];                    {Gregorian Dates    }
  15.      PTOOLDAT_Str_3    = String [3];                     {Order of elements  }
  16.      PTOOLDAT_Str_9    = String [9];                     {Day of Week        }
  17.      PTOOLDAT_Elements = Array [1..3]  of String [21];   {Parsing elements   }
  18.      PTOOLDAT_Numbers  = Array [1..3]  of Integer;       {Parsing numbers    }
  19.      PTOOLDAT_Months   = Array [1..12] of String [9];    {Months Names       }
  20.      PTOOLDAT_Days     = Array [1..7]  of PTOOLDAT_Str_9;{Days of the Week   }
  21.  
  22.  
  23. CONST
  24.  
  25.    { Gregorian Date      A string expression of up to 21 characters.
  26.      --------------      example:  02/15/50  or  February 2, 1950
  27.  
  28.                          The order and style to display the elements
  29.                          (Month, Day, Year) are determined by the
  30.                          parameters below.
  31.  
  32.                          As an argument, the date is passed as a string
  33.                          expression with 3 elements in the same order as
  34.                          displayed separated by at least one of the
  35.                          characters  / - , . ' ; : ( ) · or a space.      }
  36.  
  37.                                            {    Gregorian Date parameters    }
  38.                                            {*********************************}
  39.  PTOOLDAT_G_YrDisp  : Byte        = 2;     { # of Display Chars for Year     }
  40.                                            {     2    = 50                   }
  41.                                            {     4    = 1950                 }
  42.  PTOOLDAT_G_MoDisp  : Byte        = 2;     { # of Display Chars for Month    }
  43.                                            {     2    = 02                   }
  44.                                            {     3    = Feb                  }
  45.                                            {     9    = February             }
  46.  PTOOLDAT_G_DaDisp  : Byte        = 2;     { # of Display Chars for Day      }
  47.                                            {     2    = 15                   }
  48.  PTOOLDAT_G_Order   : String [3]  = 'MDY'; { Order of Display                }
  49.                                            {     MDY  = 02 15 50             }
  50.  PTOOLDAT_G_Sep1    : String [3]  = '/';   { 1st Separation Character        }
  51.                                            {     /    = 02/15 50             }
  52.  PTOOLDAT_G_Sep2    : String [3]  = '/';   { 2nd Separation Character        }
  53.                                            {     /    = 02/15/50             }
  54.  PTOOLDAT_G_ZeroSup : Boolean     = FALSE; { Zero Suppress Display?          }
  55.                                            {     True =  2/15/50             }
  56.                                            {*********************************}
  57.  
  58.    { The 2nd Gregorian Date is used solely as input for
  59.      the conversion function PTDGtoG                    }
  60.  
  61.                                            {  2nd Gregorian Date parameters  }
  62.                                            {*********************************}
  63.  PTOOLDAT_G2_Order  : String [3]  = 'MDY'; { Order of Input                  }
  64.                                            {*********************************}
  65.  
  66.    { Julian Date      A Real number in either of three formats:
  67.      -----------      A = ANSI Date (YYDDD)  YY is the year within century
  68.                                             DDD is the day of the year
  69.                       B = ANSI Date (YYYYDDD) YYYY is the year
  70.                                               DDD  is the day of the year
  71.                       E = Elapsed days since January 1 of the base year below.
  72.                                Note that this may result in a negative number
  73.                                if the date is previous to the base year
  74.                           CAUTION - If the base year below is changed, this
  75.                                value becomes meaningless.
  76.  
  77.  
  78.  
  79.                                            {      Julian Date parameter      }
  80.                                            {*********************************}
  81.  PTOOLDAT_J_Type    : Char        = 'E';   { Julian Date Type                }
  82.                                            {     A    = ANSI Date (YYDDD)    }
  83.                                            {                      (50046)    }
  84.                                            {     B    = ANSI DATE (YYYYDDD)  }
  85.                                            {                      (1950046)  }
  86.                                            {     E    = Days since January   }
  87.                                            {                1st of base year }
  88.                                            {                      (7350)     }
  89.                                            {*********************************}
  90.  
  91.    { Short Date      An integer value representing the number of days since
  92.      ----------      January 1 of the base year below minus 32765. USE WITH
  93.                      CAUTION, dates earlier than the base year or later than
  94.                      179 years after the base year cannot be calculated (date
  95.                      returned is -32766). This date is useful for saving disk
  96.                      or table storage only - it must be changed back to
  97.                      another form to be used.
  98.  
  99.      Day of Week      A String expression of up to 9 characters
  100.      -----------      The format depends on the parameter below:
  101.  
  102.                 1 = 1      2      3       4         5        6      7
  103.                 3 = Sun    Mon    Tue     Wed       Thr      FrI    Sat
  104.                 9 = Sunday Monday Tuesday Wednesday Thursday Friday Saturday }
  105.  
  106.                                            {      Day of Week parameter      }
  107.                                            {*********************************}
  108.  PTOOLDAT_Day_Type  : Byte        = 3;     { Day of week Type                }
  109.                                            {     1    = 4                    }
  110.                                            {     2    = We                   }
  111.                                            {     3    = Wed                  }
  112.                                            {     9    = Wednesday            }
  113.                                            {*********************************}
  114.  
  115.     {Base Year        This is used for dates in Julian Type B format, for
  116.      ---------           conversion of dates entered without a century, and
  117.                          for Short format dates.
  118.                       If Base Year is 1930 then the year 50 will be calculated
  119.                          as 1950, the year 29 will be calculated as 2029.    }
  120.  
  121.  PTOOLDAT_BaseYear  : Integer     = 1901;
  122.  
  123. {*****   PTOOLDAT Internal usage fields follow:  *****}
  124.  
  125.  PTOOLDAT_Element   : PTOOLDAT_Elements = (' ', ' ', ' ');
  126.  PTOOLDAT_Number    : PTOOLDAT_Numbers  = (0, 0, 0);
  127.  PTOOLDAT_ElY       : String [9] = '         ';
  128.  PTOOLDAT_ElM       : String [9] = '         ';
  129.  PTOOLDAT_ElD       : String [9] = '         ';
  130.  PTOOLDAT_NumY      : Integer = 0;
  131.  PTOOLDAT_NumM      : Integer = 0;
  132.  PTOOLDAT_NumD      : Integer = 0;
  133.  
  134.  PTOOLDAT_Mon   : PTOOLDAT_Months    = ('Jan', 'Feb', 'Mar', 'Apr', 'May',
  135.                                         'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
  136.                                         'Nov', 'Dec');
  137.  PTOOLDAT_Month : PTOOLDAT_Months    = ('January', 'February', 'March',
  138.                                         'April', 'May', 'June', 'July',
  139.                                         'August', 'September', 'October',
  140.                                         'November', 'December');
  141.  PTOOLDAT_Day   : PTOOLDAT_Days      = ('Sun', 'Mon', 'Tue', 'Wed', 'Thr',
  142.                                         'Fri', 'Sat');
  143.  PTOOLDAT_DayOW : PTOOLDAT_Days      = ('Sunday', 'Monday', 'Tuesday',
  144.                                         'Wednesday', 'Thursday', 'Friday',
  145.                                         'Saturday');
  146.  
  147.  
  148. { Internal FUNCTIONs Begin Here ******************************************* }
  149.  
  150.  
  151. PROCEDURE PTOOLDAT_Parse (VAR Test               : PTOOLDAT_Str_21;
  152.                           VAR Number_of_Elements : Integer);
  153.  
  154. Var
  155.    I, J, E : Byte;                             { Get elements of input }
  156.                                                { Any of the characters }
  157. Begin                                          { below may seperate    }
  158.      I := 1;                                   { the elements.         }
  159.      For E := 1 to 3 do
  160.          Begin
  161.               While (Test [I] in
  162.                           ['/', '-', ',', '.', ';', ':', '(', ')', '·', ' '])
  163.                 and (I <= Length (Test)) do
  164.                     I := I + 1;
  165.               J := 1;
  166.               While (not (Test [I] in
  167.                           ['/', '-', ',', '.', ';', ':', '(', ')', '·', ' ']))
  168.                 and (I <= Length (Test)) 
  169.                 and ((I <= E*2) or (length(Test) > 6)) do
  170.                     Begin
  171.                          PTOOLDAT_Element [E] [J] := Test [I];
  172.                          J := J + 1;
  173.                          I := I + 1;
  174.                          Number_of_Elements := E;
  175.                          PTOOLDAT_Element [E] [0] := Char (J - 1);
  176.                     End;
  177.          End;
  178.      While (Test [I] in ['/', '-', ',', '.', ';', ':', '(', ')', '·', ' '])
  179.        and (I <= Length (Test)) do
  180.            I := I + 1;
  181.      If (not (Test [I] in ['/', '-', ',', '.', ';', ':', '(', ')', '·', ' ']))
  182.        and (I <= Length (Test)) then
  183.            Number_of_Elements := 4;
  184. End;
  185.  
  186.  
  187. FUNCTION PTOOLDAT_Set_Century (InYear : Integer) : Integer;
  188.  
  189. Var                                   { Add correct century based on Base }
  190.    Century : Integer;                 { Year - if less than then next     }
  191.                                       { century else same.                }
  192. Begin
  193.      Century := Trunc (Int ( PTOOLDAT_BaseYear / 100)) * 100;
  194.      If InYear >= PTOOLDAT_BaseYear - Century
  195.      then PTOOLDAT_Set_Century := Century + InYear
  196.      else PTOOLDAT_Set_Century := Century + InYear + 100;
  197. End;
  198.  
  199.  
  200. FUNCTION PTOOLDAT_GetNum (Test : PTOOLDAT_Str_21; MDY : Char) : Integer;
  201.  
  202. Var
  203.    Number    : Integer;                         { Get the number of the }
  204.    Code      : Integer;                         { Month, Day, or Year   }
  205.    I, J      : Byte;
  206.    Year      : Integer;
  207.    Century   : Integer;
  208.    Ch        : Char;
  209.    TestMon   : String [3];
  210.    TestMonth : String [9];
  211.  
  212. Begin
  213.      PTOOLDAT_GetNum := 0;
  214.      Number := 0;
  215.      Val (Test, Number, Code);
  216.      Case MDY of
  217.       'M' : If (Code = 0)
  218.            and (Number in [1..12]) then
  219.                PTOOLDAT_GetNum := Number
  220.             else
  221.                Begin
  222.                     For I := 1 to 21 do
  223.                         Begin
  224.                              Ch := Test [I];
  225.                              Test [I] := UpCase (Ch);
  226.                         End;
  227.                     For I := 1 to 12 do
  228.                         Begin
  229.                              For J := 1 to 3 do
  230.   { Check for    }               Begin
  231.   { alphabetic   }                    Ch := PTOOLDAT_Mon [I] [J];
  232.   { month inputs }                    TestMon [J] := UpCase (Ch);
  233.                                  End;
  234.                              For J := 1 to 9 do
  235.                                  Begin
  236.                                       Ch := PTOOLDAT_Month [I] [J];
  237.                                       TestMonth [J] := UpCase (Ch);
  238.                                  End;
  239.                              TestMon [0] := PTOOLDAT_Mon [I] [0];
  240.                              TestMonth [0] := PTOOLDAT_Month [I] [0];
  241.                              If (Test = TestMon)
  242.                              or (Test = TestMonth) then
  243.                                 PTOOLDAT_GetNum := I;
  244.                         End;
  245.                End;
  246.       'D' : If Code = 0 then
  247.                If Number in [1..31] then PTOOLDAT_GetNum := Number;
  248.       'Y' : If Code = 0 then
  249.                If Number > 99 then PTOOLDAT_GetNum := Number
  250.                  else
  251.                   PTOOLDAT_GetNum := PTOOLDAT_Set_Century (Number);
  252.       End; {Case}
  253. End;
  254.  
  255.  
  256. FUNCTION PTOOLDAT_Leap_Year (InYear : Integer) : Boolean;
  257.  
  258. Var                                          { Find out if it's a Leap Year }
  259.    Century : Integer;
  260.    Year    : Integer;
  261.  
  262. Begin
  263.      If InYear < 100 then
  264.         InYear := PTOOLDAT_Set_Century (InYear);
  265.      Century := Trunc (Int (InYear / 100));
  266.      Year := InYear - (Century * 100);
  267.      PTOOLDAT_Leap_Year := True;
  268.      If Year <> (Trunc (Int (Year / 4)) * 4) then PTOOLDAT_Leap_Year := False;
  269.      If (Year = 0) and
  270.         (Century = (Trunc (Int (Century / 4)) * 4)) and
  271.         (Century <> (Trunc (Int (Century / 10)) * 10)) then
  272.            PTOOLDAT_Leap_Year := False;
  273. End;
  274.  
  275.  
  276. FUNCTION PTOOLDAT_G_Check (Test : PTOOLDAT_Str_21;
  277.                            OrderIn : PTOOLDAT_Str_3)
  278.                           : Boolean;
  279.  
  280. Var                                      { Find out if the Element areas    }
  281.    Num_of_El : Integer;                  { represent a valid Gregorian date }
  282.    E         : Byte;                     { and set Number areas             }
  283.    Ok        : Boolean;
  284.  
  285. Begin
  286.      Ok := True;
  287.      PTOOLDAT_Parse (Test, Num_of_El);
  288.      If Num_of_El <> 3 then
  289.         Ok := False;
  290.      For E := 1 to 3 do
  291.          Begin
  292.               PTOOLDAT_Number [E] := PTOOLDAT_GetNum (PTOOLDAT_Element [E],
  293.                                                       OrderIn [E]);
  294.               If PTOOLDAT_Number [E] = 0 then Ok := False;
  295.          End;
  296.      If Ok = True then
  297.         Begin
  298.              For E := 1 to 3 do
  299.                  Case OrderIn [E] of
  300.                   'Y' : PTOOLDAT_NumY := PTOOLDAT_Number [E];
  301.                   'M' : PTOOLDAT_NumM := PTOOLDAT_Number [E];
  302.                   'D' : PTOOLDAT_NumD := PTOOLDAT_Number [E];
  303.                   End; {Case}
  304.              If PTOOLDAT_NumD > 30 then
  305.                 If not (PTOOLDAT_NumM in [1, 3, 5, 7, 8, 10, 12]) then
  306.                    Ok := False;
  307.              If (PTOOLDAT_NumD > 29) and
  308.                 (PTOOLDAT_NumM = 2) then Ok := False;
  309.              If (PTOOLDAT_NumD > 28) and
  310.                 (PTOOLDAT_NumM = 2) and
  311.                 (PTOOLDAT_Leap_Year (PTOOLDAT_NumY) = False) then
  312.                 Ok := False;
  313.         End;
  314.      PTOOLDAT_G_Check := Ok;
  315. End;
  316.  
  317.  
  318. FUNCTION PTOOLDAT_Make_G : PTOOLDAT_Str_21;
  319.  
  320. Var                              { Transform the Number & Element areas }
  321.    E      : Byte;                { into a Gregorian date                }
  322.    Output : String [21];
  323.  
  324. Begin
  325.      If PTOOLDAT_G_YrDisp = 2 then
  326.         Str (PTOOLDAT_NumY - (Trunc (Int (PTOOLDAT_NumY / 100)) * 100):2,
  327.              PTOOLDAT_ElY)
  328.      else
  329.         Str (PTOOLDAT_NumY:4, PTOOLDAT_ElY);
  330.      If PTOOLDAT_ElY [1] = ' ' then PTOOLDAT_ElY [1] := '0';
  331.      Case PTOOLDAT_G_MoDisp of
  332.       2 : Begin
  333.                Str (PTOOLDAT_NumM:2, PTOOLDAT_ElM);
  334.                If PTOOLDAT_ElM [1] = ' ' then
  335.                   If PTOOLDAT_G_ZeroSup then Delete (PTOOLDAT_ElM, 1, 1)
  336.                                         else PTOOLDAT_ElM [1] := '0';
  337.           End;
  338.       3 : PTOOLDAT_ElM := PTOOLDAT_Mon [PTOOLDAT_NumM];
  339.       9 : PTOOLDAT_ElM := PTOOLDAT_Month [PTOOLDAT_NumM];
  340.      End; {Case}
  341.      Str (PTOOLDAT_NumD:2, PTOOLDAT_ElD);
  342.      If PTOOLDAT_ElD [1] = ' ' then
  343.         If PTOOLDAT_G_ZeroSup then Delete (PTOOLDAT_ElD, 1, 1)
  344.                               else PTOOLDAT_ElD [1] := '0';
  345.      Output := '';
  346.      For E := 1 to 3 do
  347.          Begin
  348.               Case PTOOLDAT_G_Order [E] of
  349.                'Y' : Output := Output + PTOOLDAT_ElY;
  350.                'M' : Output := Output + PTOOLDAT_ElM;
  351.                'D' : Output := Output + PTOOLDAT_ElD;
  352.                End; {Case}
  353.               Case E of
  354.                1 : Output := Output + PTOOLDAT_G_Sep1;
  355.                2 : Output := Output + PTOOLDAT_G_Sep2;
  356.                End; {Case}
  357.          End;
  358.      PTOOLDAT_Make_G := Output;
  359. End;
  360.  
  361.  
  362. FUNCTION PTOOLDAT_G_Convert (Test  : PTOOLDAT_Str_21;
  363.                              OrderIn, OrderOut : PTOOLDAT_Str_3)
  364.                             : PTOOLDAT_Str_21;
  365.  
  366. Begin                                               { Transform date formats }
  367.      PTOOLDAT_G_Convert := ' ';
  368.      If PTOOLDAT_G_Check (Test, OrderIn) then
  369.         PTOOLDAT_G_Convert := PTOOLDAT_Make_G;
  370. End;
  371.  
  372.  
  373. FUNCTION PTOOLDAT_Day_of_Year : Integer;
  374.  
  375. Var                                           { Get Day of Year }
  376.    Result : Integer;
  377.  
  378. Const
  379.      Days : Array [1..12] of Integer = (0, 31, 59, 90, 120, 151, 181, 212,
  380.                                         243, 273, 304, 334);
  381.  
  382. Begin
  383.       Result := Days [PTOOLDAT_NumM] + PTOOLDAT_NumD;
  384.       If (PTOOLDAT_NumM > 2) and
  385.          (PTOOLDAT_Leap_Year (PTOOLDAT_NumY)) then
  386.          Result := Result + 1;
  387.       PTOOLDAT_Day_of_Year := Result;
  388. End;
  389.  
  390.  
  391. FUNCTION PTOOLDAT_J_Type_E : Real;
  392.  
  393. Var                                        { Get 'E' type Julian Date from }
  394.    Accum : Real;                           { Number area                   }
  395.    I, J  : Integer;
  396.  
  397. Begin
  398.      If PTOOLDAT_BaseYear <= PTOOLDAT_NumY then
  399.         Begin
  400.              J := Trunc ( Int((PTOOLDAT_NumY - PTOOLDAT_BaseYear) / 4));
  401.              Accum := Int (J) * 1461;
  402.              I := PTOOLDAT_BaseYear + (J * 4);
  403.              While I < PTOOLDAT_NumY do
  404.                    Begin
  405.                         If PTOOLDAT_Leap_Year (I) then Accum := Accum + 366
  406.                                                   else Accum := Accum + 365;
  407.                         I := I + 1;
  408.                   End;
  409.              PTOOLDAT_J_Type_E := Accum + PTOOLDAT_Day_of_Year - 1;
  410.         End
  411.      else
  412.         Begin
  413.              If PTOOLDAT_Leap_Year (PTOOLDAT_NumY) then
  414.                 Accum := 367 - PTOOLDAT_Day_of_Year
  415.              else
  416.                 Accum := 366 - PTOOLDAT_Day_of_Year;
  417.              J := Trunc ( Int ((PTOOLDAT_BaseYear - PTOOLDAT_NumY) / 4));
  418.              Accum := Accum + (Int (J) * 1461);
  419.              I := PTOOLDAT_NumY + 1 + (J * 4);
  420.              While I < PTOOLDAT_BaseYear do
  421.                    Begin
  422.                         If PTOOLDAT_Leap_Year (I) then Accum := Accum + 366
  423.                                                   else Accum := Accum + 365;
  424.                         I := I + 1;
  425.                    End;
  426.              PTOOLDAT_J_Type_E := Accum * -1;
  427.         End;
  428. End;
  429.  
  430.  
  431. PROCEDURE PTOOLDAT_Set_M_D (Input : Real);
  432.  
  433. Var                                               { Get Month & Day }
  434.    InInt    : Integer;                            { from DDD        }
  435.    I        : Byte;
  436.    J        : Integer;
  437.    DayTest  : Array [1..12] of Integer;
  438.  
  439. Const
  440.      Days : Array [1..12] of Integer = (0, 31, 59, 90, 120, 151, 181, 212,
  441.                                         243, 273, 304, 334);
  442.  
  443. Begin
  444.      InInt := Trunc (Input - ((Int (Trunc (Input / 1000))) * 1000));
  445.      Move (Days, DayTest, 24);
  446.      If PTOOLDAT_Leap_Year (PTOOLDAT_NumY) then
  447.         For I := 3 to 12 do
  448.             DayTest [I] := DayTest [I] + 1;
  449.      For I := 1 to 12 do
  450.          If InInt > DayTest [I] then
  451.             Begin
  452.                  PTOOLDAT_NumM := I;
  453.                  J := DayTest [I];
  454.             End;
  455.      PTOOLDAT_NumD := InInt - J;
  456. End;
  457.  
  458.  
  459. PROCEDURE PTOOLDAT_J_E_Eval (Input : Real);
  460.                                                 { Convert a Julian type 'E' }
  461. Var                                             { date to Number area       }
  462.    Years, Days  : Integer;
  463.    I            : Byte;
  464.    Test         : Integer;
  465.  
  466. Begin
  467.      If Input >= 0 then
  468.         Begin
  469.              Years := Trunc (Input / 1461);
  470.              Days := Trunc (Input - (Int (Years) * 1461)) + 1;
  471.              PTOOLDAT_NumY := PTOOLDAT_BaseYear;
  472.              For I := 1 to 4 do
  473.                  Begin
  474.                       If PTOOLDAT_Leap_Year (PTOOLDAT_NumY) then Test := 366
  475.                                                             else Test := 365;
  476.                       If Days > Test then
  477.                          Begin
  478.                               Days := Days - Test;
  479.                               PTOOLDAT_NumY := PTOOLDAT_NumY + 1;
  480.                          End;
  481.                  End;
  482.              PTOOLDAT_NumY := PTOOLDAT_NumY + (Years * 4);
  483.         End
  484.      else
  485.         Begin
  486.              Input := Input * -1;
  487.              Years := Trunc (Input / 1461);
  488.              Days := Trunc (Input - (Int (Years) * 1461));
  489.              PTOOLDAT_NumY := PTOOLDAT_BaseYear - 1;
  490.              For I := 1 to 4 do
  491.                  Begin
  492.                       If PTOOLDAT_Leap_Year (PTOOLDAT_NumY) then Test := 366
  493.                                                             else Test := 365;
  494.                       If Days > Test then
  495.                          Begin
  496.                               Days := Days - Test;
  497.                               PTOOLDAT_NumY := PTOOLDAT_NumY - 1;
  498.                          End;
  499.                  End;
  500.              PTOOLDAT_NumY := PTOOLDAT_NumY - (Years * 4);
  501.              If PTOOLDAT_Leap_Year (PTOOLDAT_NumY) then Days := 367 - Days
  502.                                                    else Days := 366 - Days;
  503.         End;
  504.      PTOOLDAT_Set_M_D (Days);
  505. End;
  506.  
  507.  
  508. PROCEDURE PTOOLDAT_J_AB_Set_Y (Input : Real);     { Put Year in Number area }
  509.                                                   { From YYmmm              }
  510. Begin
  511.      PTOOLDAT_NumY := Trunc (Input / 1000);
  512.      If PTOOLDAT_NumY < 100 then
  513.         PTOOLDAT_NumY := PTOOLDAT_Set_Century (PTOOLDAT_NumY);
  514. End;
  515.  
  516.  
  517. FUNCTION PTOOLDAT_Get_Jul : Real;
  518.                                           { Get Julian Date from Number area }
  519. Begin
  520.      Case PTOOLDAT_J_Type of
  521.       'A' : PTOOLDAT_Get_Jul := (Int (PTOOLDAT_NumY) * 1000)
  522.                               - (Int (PTOOLDAT_NumY / 100) * 100000.0)
  523.                               + Int (PTOOLDAT_Day_of_Year);
  524.       'B' : PTOOLDAT_Get_Jul := (Int (PTOOLDAT_NumY) * 1000)
  525.                               + Int (PTOOLDAT_Day_of_Year);
  526.       'E' : PTOOLDAT_Get_Jul := PTOOLDAT_J_Type_E;
  527.       End; {Case}
  528. End;
  529.  
  530.  
  531. FUNCTION PTOOLDAT_Get_S : Integer;
  532.                                       { Get Short date from Number area }
  533. Var
  534.    Julian : Real;
  535.  
  536. Const
  537.      MaxJul : Real = 65532.0;
  538.  
  539. Begin
  540.      Julian := PTOOLDAT_J_Type_E;
  541.      If (Julian >= 0) and
  542.         (Julian <= MaxJul) then PTOOLDAT_Get_S := Trunc (Julian - 32765)
  543.                            else PTOOLDAT_Get_S := -32766;
  544. End;
  545.  
  546.  
  547. FUNCTION PTOOLDAT_DOW (Day : Integer) : PTOOLDAT_Str_9;
  548.  
  549. Var
  550.    Hold_DOW : PTOOLDAT_Str_9;                     { Convert 1 - 7 to day }
  551.                                                   { of week verbage      }
  552. Begin
  553.      Case PTOOLDAT_Day_Type of
  554.       1 : Begin
  555.                Str (Day:1, Hold_DOW);
  556.                PTOOLDAT_DOW := Hold_DOW;
  557.           End;
  558.       3 : PTOOLDAT_DOW := PTOOLDAT_Day [Day];
  559.       9 : PTOOLDAT_DOW := PTOOLDAT_DayOW [Day];
  560.       End; {Case}
  561. End;
  562.  
  563.  
  564. FUNCTION PTOOLDAT_Get_Date : PTOOLDAT_Str_21;
  565.  
  566. Type                                         { BIOS call to get current date }
  567.     BiosCall = Record
  568.                Ax, Bx, Cx, Dx, Bp, Si, Ds, Es, Flags : Integer;
  569.                End;
  570.  
  571. Var
  572.     BiosRec          : BiosCall;
  573.     Year, Month, Day : String [4];
  574.  
  575. Begin
  576.      With BiosRec do
  577.           Begin
  578.                Ax := $2a shl 8;
  579.           End;
  580.      MsDos (BiosRec);
  581.      With BiosRec do
  582.           Begin
  583.                Str (Cx, Year);
  584.                Str (Dx mod 256, Day);
  585.                Str (Dx shr 8, Month);
  586.           End;
  587.      PTOOLDAT_Get_Date := Year + ' ' + Month + ' ' + Day;
  588. End;
  589.  
  590.  
  591. {Called FUNCTIONs Begin Here ******************************************** }
  592.  
  593. FUNCTION PTDGtoJ (Input : PTOOLDAT_Str_21) : Real;
  594. begin
  595.      If PTOOLDAT_G_Check (Input, PTOOLDAT_G_Order) then
  596.         PTDGtoJ := PTOOLDAT_Get_Jul;
  597. end;
  598.  
  599. {FUNCTIONs available in PTOOLTIM.INC are:
  600.  
  601.                                (Result)
  602.  
  603.  PTTValid  (String)          : Boolean - True if argument is valid time
  604.  PTTHtoD   (String)          : Real    - Convert argument (HH:MM:SS String) to
  605.                                          a Decimal Time
  606.  PTTDtoH   (Real)            : String  - Convert argument (Decimal Time) to a
  607.                                          HH:MM:SS String
  608.  PTTHtoH   (String)          : String  - Convert argument (HH:MM:SS String) to
  609.                                          HH:MM:SS String in display format.
  610.  PTTAdd    (String, Real)    : String  - Add argument-2 number of Days, Hours
  611.                                          Minutes or Seconds (depending on
  612.                                          Decimal Time Type) to argument-1
  613.                                          (HH:MM:SS String) and express result
  614.                                          as a HH:MM:SS String
  615.  PTTComp  (String, String)  : Real    - Subtract argument-2 (HH:MM:SS String)
  616.                                          from argument-1 (HH:MM:SS String)
  617.                                          giving number of Days, Hours, Minutes
  618.                                          or Seconds (depending on Decimal Time
  619.                                          Type)
  620.  PTTHCurr                    : String  - Current (system) Time as a HH:MM:SS
  621.                                          String
  622.  PTTDCurr                    : Real    - Current (system) Time as Decimal
  623.                                          Days, Hours, Minutes or Seconds
  624.                                          (depending on Decimal Time Type)   }
  625.  
  626.  
  627.  
  628. { Constant Values  (Parameters) Begin Here ******************************** }
  629.  
  630.  
  631. TYPE
  632.  
  633.      PTOOLTIM_Str_11   = String [11];
  634.      PTOOLTIM_Elements = Array [1..4] of String [11];
  635.  
  636.  
  637. CONST
  638.  
  639.    { HH:MM:SS String     A string expression of up to 11 characters.
  640.      ---------------     example:  12:02:54 am
  641.  
  642.                          The style to display the elements (HH, MM, SS)
  643.                          is determined by the parameters below.
  644.  
  645.                          As an argument, the time is passed as a string
  646.                          expression with 3 or 4 elements separated by at
  647.                          least one of the characters  / - , . ' ; : ( )
  648.                          or a space.                                         }
  649.  
  650.                                            {   HH:MM:SS String parameters    }
  651.                                            {*********************************}
  652.  PTOOLTIM_HH_Disp   : Byte        = 24;    { Hour Display format             }
  653.                                            {   12    = 12 hour format        }
  654.                                            {   24    = 24 hour format        }
  655.  PTOOLTIM_SS_Disp   : Char        = 'S';   { Seconds Display format          }
  656.                                            {   'S'   = Display Seconds       }
  657.                                            {   ' '   = Display HH:MM only    }
  658.                                            {*********************************}
  659.  
  660.  
  661.    { Decimal Time     A Real number in either of four formats:
  662.      ------------        D = Decimal Days
  663.                          H = Decimal Hours
  664.                          M = Decimal Minutes
  665.                          S = Decimal Seconds }
  666.  
  667.                                            {      Decimal Time parameter     }
  668.                                            {*********************************}
  669.  PTOOLTIM_D_Type    : Char        = 'S';   { Decimal Time Type               }
  670.                                            {*********************************}
  671.  
  672.  
  673. { ****** Areas for internal use follow ****** }
  674.  
  675.  PTOOLTIM_Element   : PTOOLTIM_Elements = (' ', ' ', ' ', ' ');
  676.  PTOOLTIM_NumH      : Integer = 0;
  677.  PTOOLTIM_NumM      : Integer = 0;
  678.  PTOOLTIM_NumS      : Integer = 0;
  679.  
  680.  
  681.  
  682. { Internal FUNCTIONs Begin Here ******************************************* }
  683.  
  684.  
  685. PROCEDURE PTOOLTIM_Parse (VAR Test               : PTOOLTIM_Str_11;
  686.                           VAR Number_of_Elements : Integer);
  687. Var
  688.    I, J, K, E : Byte;                          { Get elements of input }
  689.                                                { Any of the characters }
  690. Begin                                          { below may seperate    }
  691.      I := 1;                                   { the elements.         }
  692.      K := 1;
  693.      For E := 1 to 3 do
  694.          Begin
  695.               PTOOLTIM_Element [E] := ' ';
  696.               While (not (Test [I] in ['0' .. '9']))
  697.                 and (I <= Length (Test)) do
  698.                     Begin
  699.                          PTOOLTIM_Element [4] [K] := Test [I];
  700.                          K := K + 1;
  701.                          I := I + 1;
  702.                     End;
  703.               J := 1;
  704.               While (Test [I] in ['0' .. '9'])
  705.                 and (I <= Length (Test)) do
  706.                     Begin
  707.                          PTOOLTIM_Element [E] [J] := Test [I];
  708.                          J := J + 1;
  709.                          I := I + 1;
  710.                          Number_of_Elements := E;
  711.                          PTOOLTIM_Element [E] [0] := Char (J - 1);
  712.                     End;
  713.          End;
  714.      While I <= Length (Test) do
  715.            Begin
  716.                 PTOOLTIM_Element [4] [K] := Test [I];
  717.                 K := K + 1;
  718.                 I := I + 1;
  719.            End;
  720.      PTOOLTIM_Element [4] [0] := Char (K - 1);
  721. End;
  722.  
  723. FUNCTION PTOOLTIM_H_Check (Test : PTOOLTIM_Str_11) : Boolean;
  724. Var                                      { Find out if the Element areas     }
  725.    Num_of_El : Integer;                  { represent a valid HH:MM:SS String }
  726.    Code      : Integer;                  { and set Number areas              }
  727.  
  728. Begin
  729.      PTOOLTIM_H_Check := True;
  730.      PTOOLTIM_Parse (Test, Num_of_El);
  731.      If (Num_of_El < 2) or
  732.         (Num_of_El > 3) then
  733.         PTOOLTIM_H_Check := False;
  734.      Val (PTOOLTIM_Element [1], PTOOLTIM_NumH, Code);
  735.      If Code <> 0 then PTOOLTIM_H_Check := False;
  736.      Val (PTOOLTIM_Element [2], PTOOLTIM_NumM, Code);
  737.      If Code <> 0 then PTOOLTIM_H_Check := False;
  738.      PTOOLTIM_NumS := 0;
  739.      If Num_of_El = 3 then
  740.              Val (PTOOLTIM_Element [3], PTOOLTIM_NumS, Code);
  741.      If (Pos ('p', PTOOLTIM_Element [4]) <> 0)
  742.      or (Pos ('P', PTOOLTIM_Element [4]) <> 0) then
  743.         If PTOOLTIM_NumH < 12  then
  744.            PTOOLTIM_NumH := PTOOLTIM_NumH + 12
  745.            else begin end
  746.      else
  747.         If PTOOLTIM_NumH = 12 then PTOOLTIM_NumH := PTOOLTIM_NumH - 12;
  748.      If (PTOOLTIM_NumH > 23) or
  749.         (PTOOLTIM_NumM > 59) or
  750.         (PTOOLTIM_NumS > 59) or
  751.         (PTOOLTIM_NumH < 0) or
  752.         (PTOOLTIM_NumM < 0) or
  753.         (PTOOLTIM_NumS < 0) then PTOOLTIM_H_Check := False;
  754. End;
  755.  
  756.  
  757. FUNCTION PTOOLTIM_Make_H : PTOOLTIM_Str_11;
  758. Var                              { Transform the Number areas }
  759.    Output : String [11];         { into a HH:MM:SS String     }
  760.    Work   : String [2];
  761.  
  762. Begin
  763.      Case PTOOLTIM_HH_Disp of
  764.       12 : If PTOOLTIM_NumH > 12 then Str (PTOOLTIM_NumH - 12:2, Output)
  765.            else
  766.               If PTOOLTIM_NumH = 0 then Output := '12'
  767.               else
  768.                  Str (PTOOLTIM_NumH:2, Output);
  769.       24 : Str (PTOOLTIM_NumH:2, Output);
  770.       End; {Case}
  771.      If Output [1] = ' ' then Delete (Output, 1, 1);
  772.      Str (PTOOLTIM_NumM:2, Work);
  773.      If Work [1] = ' ' then Work [1] := '0';
  774.      Output := Output + ':' + Work;
  775.      If PTOOLTIM_SS_Disp <> ' ' then
  776.         Begin
  777.              Str (PTOOLTIM_NumS:2, Work);
  778.              If Work [1] = ' ' then Work [1] := '0';
  779.              If PTOOLTIM_SS_Disp = 'S' then Output := Output + ':' + Work
  780.                                        else Output := Output + '.' + Work;
  781.         End;
  782.      If PTOOLTIM_HH_Disp = 12 then
  783.      If PTOOLTIM_NumH < 12 then Output := Output + ' am'
  784.                            else Output := Output + ' pm';
  785.      PTOOLTIM_Make_H := Output;
  786. End;
  787.  
  788.  
  789. FUNCTION PTOOLTIM_Get_D_Days : Real;  { Get Decimal Days from Number area }
  790. Begin
  791.      PTOOLTIM_Get_D_Days := (Int (PTOOLTIM_NumH) / 24)
  792.                           + (Int (PTOOLTIM_NumM) / 1440)
  793.                           + (Int (PTOOLTIM_NumS) / 86400.0);
  794. End;
  795.  
  796.  
  797. FUNCTION PTOOLTIM_Get_Decimal : Real;
  798.                                         { Get Decimal time from }
  799. Begin                                   { Number area           }
  800.      Case PTOOLTIM_D_Type of
  801.       'D' : PTOOLTIM_Get_Decimal := PTOOLTIM_Get_D_Days;
  802.       'H' : PTOOLTIM_Get_Decimal := PTOOLTIM_Get_D_Days * 24;
  803.       'M' : PTOOLTIM_Get_Decimal := PTOOLTIM_Get_D_Days * 1440;
  804.       'S' : PTOOLTIM_Get_Decimal := PTOOLTIM_GET_D_Days * 86400.0;
  805.       End; {Case}
  806. End;
  807.  
  808.  
  809.  
  810. PROCEDURE PTOOLTIM_Get_Time;
  811.                                          { BIOS call to put current time }
  812. Type                                     { into Number areas             }
  813.     BiosCall = Record
  814.                Ax, Bx, Cx, Dx, Bp, Si, Ds, Es, Flags : Integer;
  815.                End;
  816.  
  817. Var
  818.     BiosRec : BiosCall;
  819.     Ah, Al  : Byte;
  820.  
  821. Begin
  822.      Ah := $2c;
  823.      With BiosRec do
  824.           Begin
  825.                Ax := Ah shl 8 + Al;
  826.           End;
  827.      Intr ($21, BiosRec);
  828.      With BiosRec do
  829.           Begin
  830.                PTOOLTIM_NumH := Cx shr 8;
  831.                PTOOLTIM_NumM := Cx mod 256;
  832.                PTOOLTIM_NumS := Dx shr 8;
  833.           End;
  834. End;
  835.  
  836.  
  837. {Called FUNCTIONs Begin Here ******************************************** }
  838.  
  839.  
  840. (*FUNCTION PTTValid (Test : PTOOLTIM_Str_11) : Boolean;
  841. begin
  842.      PTTValid := PTOOLTIM_H_Check (Test);
  843. end;*)
  844.  
  845.  
  846. FUNCTION PTTHtoD (Input : PTOOLTIM_Str_11) : Real;
  847. begin
  848.      If PTOOLTIM_H_Check (Input) then
  849.         PTTHtoD := PTOOLTIM_Get_Decimal;
  850. end;
  851.  
  852.  
  853. FUNCTION PTTDtoH (Input : Real) : PTOOLTIM_Str_11;
  854. begin
  855.      Case PTOOLTIM_D_Type of
  856.       'H' : Input := Input / 24;
  857.       'M' : Input := Input / 1440;
  858.       'S' : Input := Input / 86400.0;
  859.       End; {Case}
  860.      Input := Frac (Input);
  861.      PTOOLTIM_NumH := Trunc (Input * 24.001);
  862.      PTOOLTIM_NumM := Trunc ((Input - (Int (PTOOLTIM_NumH) / 24)) * 1440.001);
  863.      PTOOLTIM_NumS := Trunc ((Input - (Int (PTOOLTIM_NumH) / 24)
  864.                                     - (Int (PTOOLTIM_NumM) / 1440))
  865.                                         * 86400.001);
  866.      PTTDtoH := PTOOLTIM_Make_H;
  867. end;
  868.  
  869.  
  870. OVERLAY FUNCTION PTTComp (Minuend, Subtrahend : PTOOLTIM_Str_11) : Real;
  871. VAR
  872.    HoldNum : Real;
  873.  
  874. begin
  875.      HoldNum := PTTHtoD (Minuend);
  876.      PTTComp := HoldNum - PTTHtoD (Subtrahend);
  877. end;
  878.  
  879.  
  880. OVERLAY FUNCTION PTTHCurr : PTOOLTIM_Str_11;
  881. begin
  882.      PTOOLTIM_Get_Time;
  883.      PTTHCurr := PTOOLTIM_Make_H;
  884. end;
  885.  
  886.  
  887. OVERLAY FUNCTION PTTDCurr : Real;
  888. begin
  889.      PTOOLTIM_Get_Time;
  890.      PTTDCurr := PTOOLTIM_Get_Decimal;
  891. end;
  892.  
  893. OVERLAY FUNCTION PTDGComp (Minuend, Subtrahend : PTOOLDAT_Str_21) : Real;
  894. VAR
  895.    Hold_Jul_Type : Char;
  896.  
  897. begin
  898.      Hold_Jul_Type := PTOOLDAT_J_Type;
  899.      PTOOLDAT_J_Type := 'E';
  900.      PTDGComp := PTDGtoJ (Minuend) - PTDGtoJ (Subtrahend);
  901.      PTOOLDAT_J_Type := Hold_Jul_Type;
  902. end;
  903.  
  904. OVERLAY FUNCTION PTDJComp (Minuend, Subtrahend : Real) : Real;
  905. VAR
  906.    Hold_Jul : Real;
  907.  
  908. begin
  909.      If PTOOLDAT_J_Type = 'E' then PTDJComp := Minuend - Subtrahend
  910.      else
  911.         Begin
  912.              PTOOLDAT_J_AB_Set_Y (Minuend);
  913.              PTOOLDAT_Set_M_D (Minuend);
  914.              Hold_Jul := (PTOOLDAT_J_Type_E);
  915.              PTOOLDAT_J_AB_Set_Y (Subtrahend);
  916.              PTOOLDAT_Set_M_D (Subtrahend);
  917.              PTDJComp := Hold_Jul - (PTOOLDAT_J_Type_E);
  918.         End;
  919. end;
  920.  
  921.  
  922. OVERLAY FUNCTION PTDGCurr : PTOOLDAT_Str_21;
  923. begin
  924.      PTDGCurr := PTOOLDAT_G_Convert (PTOOLDAT_Get_Date,
  925.                                      'YMD', PTOOLDAT_G_Order);
  926. end;
  927.  
  928.  
  929.