home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol131 / zeller.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1984-04-29  |  1.8 KB  |  60 lines

  1.  
  2. PROCEDURE ZELLER(    M,
  3.             D,
  4.             Y        : INTEGER;
  5.             VAR ZELLER# : COMPOSITE );
  6.  
  7. { COMMENT :
  8.         GIVEN A DATE , SUCH THAT M = MONTH, D = DAY & Y = YEAR,
  9. ZELLER# DETERMINES THE NO. OF DAYS THAT HAVE ELAPSED SINCE SUNDAY THE 
  10. 28TH OF FEBRUARY IN THE YEAR 0 AD.
  11.                 THE VARIABLE CORRESPONDING TO ZELLER# MUST BE OF A TYPE 
  12. CORRESPONDING TO COMPOSITE AND MUST BE DECLARED AS FOLLOWS IN THE 
  13. CALLING PROGRAM :
  14.  
  15.     TYPE    COMPOSITE    = RECORD
  16.             KILO_DAYS  : INTEGER;
  17.             UNIT_DAYS  : INTEGER
  18.         END;
  19.  
  20.     VAR    ZELLER#        : COMPOSITE;
  21.  
  22. THE REASON FOR USING THIS RECORD TYPE IS TO ALLOW FOR NUMBERS GREATER
  23. THAN "MAXINT" TO BE CALCULATED WITHOUT THE LOSS OF PRECISION INHERENT
  24. IN FLOATING POINT FORMAT.THE TOTAL NO. OF DAYS SINCE 2/28/00 A.D. CAN
  25. BE CALCULATED AS ((1024 * ZELLER#.KILO_DAYS) + ZELLER#.UNIT_DAYS).
  26. HOWEVER IF THIS IS DONE DIRECTLY IT WILL CAUSE EITHER INTEGER OVERFLOW
  27. OR SERIOUS FLOATING POINT PRECISION LOSS.OBVIOUSLY THERE ARE A NO. OF 
  28. WAYS OF AVOIDING THIS PROBLEM (e.g.USE FIXED POINT TYPES).JUST HOW TO
  29. BEST DO SO , IN PROCEDURES USING ZELLER NUMBERS IS BEST LEFT TO THE 
  30. CALLING PROGRAM.                            }
  31.  
  32. VAR
  33.     YEAR#,MONTH#,DAY#,CENTURY# : INTEGER;
  34.  
  35. BEGIN
  36. WITH ZELLER# DO BEGIN
  37.  KILO_DAYS    := 0;
  38.  UNIT_DAYS    := 0;
  39.  YEAR#        := Y;
  40.  MONTH#        := M - 2;
  41.  IF MONTH# < 1 THEN BEGIN
  42.         MONTH# := MONTH# + 12;
  43.         YEAR#  := YEAR#  - 1;
  44.         END;
  45.  DAY#        := D;
  46.  CENTURY#    := YEAR# DIV 100;
  47.  YEAR#        := YEAR# - (100 * CENTURY#);
  48.  UNIT_DAYS    := (( 13 * MONTH# - 1) DIV 5) + DAY# + 
  49.             (YEAR# DIV 4) + (CENTURY# DIV 4);
  50.  WHILE YEAR# > 2 DO BEGIN
  51.   YEAR#        := YEAR# - 3;
  52.   KILO_DAYS    := KILO_DAYS + 1;
  53.   UNIT_DAYS    := UNIT_DAYS + 71;
  54.   END;
  55.  UNIT_DAYS    := UNIT_DAYS + (YEAR# * 365);
  56.  KILO_DAYS    := KILO_DAYS + (35 * CENTURY#);
  57.  UNIT_DAYS    := UNIT_DAYS + (684 * CENTURY#);
  58.  END; { OF : WITH ZELLER# ... }
  59. END; { OF : PROCEDURE ZELLER }
  60.