home *** CD-ROM | disk | FTP | other *** search
-
- PROCEDURE ZELLER( M,
- D,
- Y : INTEGER;
- VAR ZELLER# : COMPOSITE );
-
- { COMMENT :
- GIVEN A DATE , SUCH THAT M = MONTH, D = DAY & Y = YEAR,
- ZELLER# DETERMINES THE NO. OF DAYS THAT HAVE ELAPSED SINCE SUNDAY THE
- 28TH OF FEBRUARY IN THE YEAR 0 AD.
- THE VARIABLE CORRESPONDING TO ZELLER# MUST BE OF A TYPE
- CORRESPONDING TO COMPOSITE AND MUST BE DECLARED AS FOLLOWS IN THE
- CALLING PROGRAM :
-
- TYPE COMPOSITE = RECORD
- KILO_DAYS : INTEGER;
- UNIT_DAYS : INTEGER
- END;
-
- VAR ZELLER# : COMPOSITE;
-
- THE REASON FOR USING THIS RECORD TYPE IS TO ALLOW FOR NUMBERS GREATER
- THAN "MAXINT" TO BE CALCULATED WITHOUT THE LOSS OF PRECISION INHERENT
- IN FLOATING POINT FORMAT.THE TOTAL NO. OF DAYS SINCE 2/28/00 A.D. CAN
- BE CALCULATED AS ((1024 * ZELLER#.KILO_DAYS) + ZELLER#.UNIT_DAYS).
- HOWEVER IF THIS IS DONE DIRECTLY IT WILL CAUSE EITHER INTEGER OVERFLOW
- OR SERIOUS FLOATING POINT PRECISION LOSS.OBVIOUSLY THERE ARE A NO. OF
- WAYS OF AVOIDING THIS PROBLEM (e.g.USE FIXED POINT TYPES).JUST HOW TO
- BEST DO SO , IN PROCEDURES USING ZELLER NUMBERS IS BEST LEFT TO THE
- CALLING PROGRAM. }
-
- VAR
- YEAR#,MONTH#,DAY#,CENTURY# : INTEGER;
-
- BEGIN
- WITH ZELLER# DO BEGIN
- KILO_DAYS := 0;
- UNIT_DAYS := 0;
- YEAR# := Y;
- MONTH# := M - 2;
- IF MONTH# < 1 THEN BEGIN
- MONTH# := MONTH# + 12;
- YEAR# := YEAR# - 1;
- END;
- DAY# := D;
- CENTURY# := YEAR# DIV 100;
- YEAR# := YEAR# - (100 * CENTURY#);
- UNIT_DAYS := (( 13 * MONTH# - 1) DIV 5) + DAY# +
- (YEAR# DIV 4) + (CENTURY# DIV 4);
- WHILE YEAR# > 2 DO BEGIN
- YEAR# := YEAR# - 3;
- KILO_DAYS := KILO_DAYS + 1;
- UNIT_DAYS := UNIT_DAYS + 71;
- END;
- UNIT_DAYS := UNIT_DAYS + (YEAR# * 365);
- KILO_DAYS := KILO_DAYS + (35 * CENTURY#);
- UNIT_DAYS := UNIT_DAYS + (684 * CENTURY#);
- END; { OF : WITH ZELLER# ... }
- END; { OF : PROCEDURE ZELLER }
-