home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / JDATE.ZIP / JDATE.PAS
Encoding:
Pascal/Delphi Source File  |  1985-12-28  |  4.8 KB  |  108 lines

  1. { Julian number to date conversions -  9/10/1984
  2.     Actually, these are not Julian dates but rather just day numbers designed for use with dates in the
  3.   twentieth century. The dates are stored in a standard integer variable and range from January 1,1900 as
  4.   -32767 to sometime in the twenty-first century at +32767.  The advantage of using day numbers is that the
  5.   number of days between two dates is simply calculated as Date1-Date2.
  6.     A magic number to be remembered is the one used to convert from the dates in this format into the dates
  7.   used by Digital Research in products such as CP/M Plus.  To convert into DRI's format from mine, add 4279
  8.   to the integer value.  To convert back from DRI's format into mine, subtract 4279.
  9.     The algorithms used in these routines were taken from an article in Dr Dobb's Journal and came from
  10.   an ACM publication before that.  If an exact bibliography is desired, contact me on Compuserve [74206,21].
  11.   I am releasing any and all rights that I may have on these routines into the public domain and only hope
  12.   that any fixes or enhancements are re-released to the public.
  13.       Scott Bussinger
  14.       Professional Practice Systems
  15.       112 South 131st Street
  16.       Tacoma, Wa 98444 }
  17.  
  18. procedure DtoJ(Day,Month,Year: integer;var Julian: integer);
  19.   { Convert from a date to a Julian number -- January 1, 1900 = -32767 }
  20.   { Note that much care is taken to avoid problems with inaccurate bit representations inherent in the binary fractions
  21.     of the real numbers used as temporary variables.  Thus the seemingly unnecessary use of small fractional offsets
  22.     and int() functions }
  23.   begin
  24.   if (Year=1900) and (Month<3)                   { Handle the first two months as a special case since the general }
  25.    then                                          {   algorithm used doesn't start until March 1, 1900 }
  26.     if Month=1
  27.      then
  28.       Julian := Day-$8000                        { Compiler won't accept -32768 as a valid integer, so use the hex form }
  29.      else
  30.       Julian := Day-32737
  31.    else
  32.     begin
  33.     if Month>2
  34.      then
  35.       Month := Month-3
  36.      else
  37.       begin
  38.       Month := Month+9;
  39.       Year := Year-1
  40.       end;
  41.     Year := Year-1900;
  42.     Julian := round(-32709.0+Day+int(0.125+int(1461.0*Year+0.5)/4.0))+((153*Month+2) div 5)
  43.     end
  44.   end;
  45.  
  46. procedure JtoD(Julian: integer;var Day,Month,Year: integer);
  47.   { Convert from a Julian date to a calendar date }
  48.   { Note that much care is taken to avoid problems with inaccurate bit representations inherent in the binary fractions
  49.     of the real numbers used as temporary variables.  Thus the seemingly unnecessary use of small fractional offsets
  50.     and int() functions }
  51.   var Temp: real;
  52.   begin
  53.   Temp := int(32767.5+Julian);                   { Convert 16 bit quantity into a real number }
  54.   if Temp<58.5
  55.    then
  56.     begin                                        { The first two months of the twentieth century are handled as a special }
  57.     Year := 1900;                                {   case of the general algorithm used which handles all of the rest }
  58.     if Temp<30.5
  59.      then
  60.       begin
  61.       Month := 1;
  62.       Day := round(Temp+1.0)
  63.       end
  64.      else
  65.       begin
  66.       Month := 2;
  67.       Day := round(Temp-30.0)
  68.       end
  69.     end
  70.    else
  71.     begin
  72.     Temp := int(4.0*(Temp-59.0)+3.5);
  73.     Year := trunc(Temp/1461.0+0.00034223);     { 0.00034223 is about one half of the reciprocal of 1461.0 }
  74.     Day := succ(round(Temp-Year*1461.0) div 4);
  75.     Month := (5*Day-3) div 153;
  76.     Day := succ((5*Day-3) mod 153 div 5);
  77.     Year := Year+1900;
  78.     if Month<10
  79.      then
  80.       Month := Month+3
  81.      else
  82.       begin
  83.       Month := Month-9;
  84.       Year := succ(Year)
  85.       end
  86.     end
  87.   end;
  88.  
  89. function DayOfWeek(Julian: integer): integer;
  90.   { Return an integer representing the day of week for the date }
  91.   { Sunday = 0, etc. }
  92.   var Temp: real;
  93.   begin
  94.   Temp := Julian+32767.0;                        { Convert into a real temporary variable }
  95.   DayOfWeek := round(frac((Temp+1.0)/7.0)*7.0)   { Essentially this is a real number version of Julian mod 7 with }
  96.   end;                                           { an offset to make Sunday = 0 }
  97.  
  98. procedure WriteDate(Julian: integer);
  99.   { Write the date out to the console in long form , e.g. "Monday, September 10, 1984" }
  100.   const Days: array[0..6] of string[9]=('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
  101.         Months: array[1..12] of string[9] = ('January','February','March','April','May','June',
  102.                                              'July','August','September','October','November','December');
  103.   var Day,Month,Year: integer;
  104.   begin
  105.   JtoD(Julian,Day,Month,Year);                   { Convert into date form }
  106.   write(Days[DayOfWeek(Julian)],', ',Months[Month],' ',Day,', ',Year);
  107.   end;
  108.