unit JDates; { A unit providing Julian day numbers and date manipulations. NOTE: The range of Dates this unit will handle is 1/1/1900 to 1/1/2078 Version 1.00 - 10/26/1987 - First general release Scott Bussinger Professional Practice Systems 110 South 131st Street Tacoma, WA 98444 (206)531-8944 Compuserve 72247,2671 Version 1.01 - 10/09/1995 - Updated for use with Delphi v1.0 Lets see some other code last this long without change Dennis Passmore 1929 Mango Tree Drive Edgewater Fl, 32141 Compuserve 71240,2464 } interface uses Sysutils; const BlankDate = $FFFF; { Constant for Not-a-real-Date } type TDate = Word; TDay = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday); TDaySet = set of TDay; procedure GetDate(var Year,Month,Day,Wday: Word); { replacement for old WINDOS proc } procedure GetTime(var Hour,Min,Sec,MSec: Word); { replacement for old WINDOS proc } function CurrentJDate: Tdate; function ValidDate(Day,Month,Year: Word): boolean; { Check if the day,month,year is a real date storable in a Date variable } procedure DMYtoDate(Day,Month,Year: Word;var Julian: TDate); { Convert from day,month,year to a date } procedure DateToDMY(Julian: TDate;var Day,Month,Year: Word); { Convert from a date to day,month,year } function BumpDate(Julian: TDate;Days,Months,Years: Integer): TDate; { Add (or subtract) the number of days, months, and years to a date } function DayOfWeek(Julian: TDate): TDay; { Return the day of the week for the date } function DayString(WeekDay: TDay): string; { Return a string version of a day of the week } function MonthString(Month: Word): string; { Return a string version of a month } function DateToStr(Julian: TDate): string; { Convert a date to a sortable string } function StrToDate(StrVar: string): TDate; { Convert a sortable string form to a date } implementation procedure GetDate(var Year,Month,Day,Wday: Word); var td: TDatetime; begin td := Date; DeCodeDate(td,Year,Month,Day); Wday := sysutils.DayofWeek(td); end; procedure GetTime(var Hour,Min,Sec,MSec: Word); var td: TDatetime; begin td := Now; DecodeTime(td,Hour,Min,Sec,MSec); end; function CurrentJdate: Tdate; var y,m,d,w: word; jd: TDate; begin GetDate(y,m,d,w); DMYtoDate(d,m,y,jd); CurrentJDate:= jd; end; function ValidDate(Day,Month,Year: Word): boolean; { Check if the day,month,year is a real date storable in a Date variable } begin if {(Day<1) or }(Year<1900) or (Year>2078) then ValidDate := false else case Month of 1,3,5,7,8,10,12: ValidDate := Day <= 31; 4,6,9,11: ValidDate := Day <= 30; 2: ValidDate := Day <= 28 + ord((Year mod 4)=0)*ord(Year<>1900) else ValidDate := false end end; procedure DMYtoDate(Day,Month,Year: Word;var Julian: TDate); { Convert from day,month,year to a date } { Stored as number of days since January 1, 1900 } { Note that no error checking takes place in this routine -- use ValidDate } begin if (Year=1900) and (Month<3) then if Month = 1 then Julian := pred(Day) else Julian := Day + 30 else begin if Month > 2 then dec(Month,3) else begin inc(Month,9); dec(Year) end; dec(Year,1900); Julian := (1461*longint(Year) div 4) + ((153*Month+2) div 5) + Day + 58; end end; procedure DateToDMY(Julian: TDate;var Day,Month,Year: Word); { Convert from a date to day,month,year } var LongTemp: longint; Temp: Word; begin if Julian <= 58 then begin Year := 1900; if Julian <= 30 then begin Month := 1; Day := succ(Julian) end else begin Month := 2; Day := Julian - 30 end end else begin LongTemp := 4*longint(Julian) - 233; Year := LongTemp div 1461; Temp := LongTemp mod 1461 div 4 * 5 + 2; Month := Temp div 153; Day := Temp mod 153 div 5 + 1; inc(Year,1900); if Month < 10 then inc(Month,3) else begin dec(Month,9); inc(Year) end end end; function BumpDate(Julian: TDate;Days,Months,Years: Integer): TDate; { Add (or subtract) the number of days, months, and years to a date } { Note that months and years are added first before days } { Note further that there are no overflow/underflow checks } var Day: Word; Month: Word; Year: Word; begin DateToDMY(Julian,Day,Month,Year); Month := Month + Months - 1; Year := Year + Years + (Month div 12) - ord(Month<0); Month := (Month + 12000) mod 12 + 1; DMYtoDate(Day,Month,Year,Julian); BumpDate := Julian + Days end; function DayOfWeek(Julian: TDate): TDay; { Return the day of the week for the date } begin DayOfWeek := TDay(succ(Julian) mod 7) end; function DayString(WeekDay: TDay): string; { Return a string version of a day of the week } const DayStr: array[Sunday..Saturday] of string[9] = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'); begin DayString := DayStr[WeekDay] end; function MonthString(Month: Word): string; { Return a string version of a month } const MonthStr: array[1..12] of string[9] = ('January','February','March','April','May','June','July','August', 'September','October','November','December'); begin MonthString := MonthStr[Month] end; function DateToStr(Julian: TDate): string; { Convert a date to a sortable string - NOT displayable } const tResult: record case integer of 0: (Len: byte; W: word); 1: (Str: string[2]) end = (Str:' '); begin tResult.W := swap(Julian); DateToStr := tResult.Str end; function StrToDate(StrVar: string): TDate; { Convert a sortable string form to a date } var Temp: record Len: byte; W: word end absolute StrVar; begin StrToDate := swap(Temp.W) end; end.