A: Here is the short version. This method uses two dates and simply subtracts them. The first one is set to Jan 1 of the same year as you want to check. (This is mostly to check for leap years.) The TDateTime type is a floating point value where the value to the left of the decimal represents the date, and the value to the right is the time. Here, we take the difference and add one to get out result. We add one because out answer will be zero based.
(I thought that Scott and Dennis' method was a bit long, so I took a short cut, but left out their extra stuff.)
Version 1
Function DateFactor(MonthNum, DayNum, YearNum : Real) : Real;
Var
Factor : Real;
Begin
Factor := (365 * YearNum) + DayNum + (31 * (MonthNum - 1));
If MonthNum < 3 Then
Factor := Factor + Int((YearNum-1) / 4) -
Int(0.75 * (Int((YearNum-1) / 100) + 1))
Else
Factor := Factor - Int(0.4 * MonthNum + 2.3)
+ Int(YearNum / 4) -
Int(0.75 * (Int(YearNum / 100) + 1));
DateFactor := Factor;
End;
Function DateToJulian(DateLine : string[8]) : Integer;
Var
Factor,
MonthNum,
DayNum,
YearNum : Real;
Ti : Integer;
Begin
If Length(DateLine) = 7 Then
DateLine := '0' + DateLine;
MonthNum := 0.0;
For Ti := 1 to 2 Do
MonthNum := (10 * MonthNum) + (Ord(DateLine[Ti])-Ord('0'));
DayNum := 0.0;
For Ti := 3 to 4 Do
DayNum := (10 * DayNum) + (Ord(DateLine[Ti])-Ord('0'));
YearNum := 0.0;
For Ti := 5 to 8 Do
YearNum := (10 * YearNum) + (Ord(DateLine[Ti])-Ord('0'));
Factor := DateFactor(MonthNum, DayNum, YearNum);
DateToJulian := Trunc((Factor - 679351.0) - 32767.0);
End;
Version 2
program JULIAN;
var
JNUM: real;
month, day, year: integer;
{----------------------------------------------}
function Jul( mo, da, yr: integer): real;
{ this is an implementation of the FORTRAN one-liner:
JD(I, J, K) = K - 32075 + 1461 * (I + 4800
+ (J-14) / 12) / 4 + 367 * (j - 2 - ((J - 14) / 12) * 12) / 12 - 3 * ((
I + 4900 + (J - 14) / 12) / 100 / 4; where I,J,K are year, month, and day.
The original version takes advantage of FORTRAN's automatic truncation
of integers but requires support of integers somewhat larger than Turbo's
Maxint, hence all of the Int()'s . The variable returned is an integer
day count using 1 January 1980 as 0. }
var i, j, k, j2, ju: real;
begin
i := yr;
j := mo;
k := da;
j2 := int( (j - 14)/12 );
ju := k - 32075 + int(1461 * ( i + 4800 + j2 ) / 4 );
ju := ju + int( 367 * (j - 2 - j2 * 12) / 12);
ju := ju - int(3 * int( (i + 4900 + j2) / 100) / 4);
Jul := ju;
end; { Jul }
{----------------------------------------------}
procedure JtoD(pj: real; var mo, da, yr: integer);
{ this reverses the calculation in Jul, returning the
result in a Date_Rec }
var ju, i, j, k, l, n: real;
begin
ju := pj;
l := ju + 68569.0;
n := int( 4 * l / 146097.0);
l := l - int( (146097.0 * n + 3)/ 4 );
i := int( 4000.0 * (l+1)/1461001.0);
l := l - int(1461.0*i/4.0) + 31.0;
j := int( 80 * l/2447.0);
k := l - int( 2447.0 * j / 80.0);
l := int(j/11);
j := j+2-12*l;
i := 100*(n - 49) + i + l;
yr := trunc(i);
mo := trunc(j);
da := trunc(k);
end; { JtoD }
{-----------------MAIN-----------------------------}
begin
writeln('This program tests the Julian date algorithms.');
writeln('Enter a calendar date in the form MM DD YYYY <return>');
writeln('Enter a date of 00 00 00 to end the program.');
day := 1;
while day<>0 do begin
writeln;
write('Enter MM DD YY '); readln( month, day, year);
if day<>0 then begin
JNUM := Jul( month, day,
year);
writeln('The Julian # of ',month,'/',day,'/',year,
' is ', JNUM:10:0);
JtoD( JNUM, month, day, year);
Writeln('The date corresponding to ',
JNUM:10:0, ' is ', month,'/',day,'/',year);
end;
end;
writeln('That''s all folks.....');
end.
This function calculates the number of days since the first of the year.
function DayOfYear(TheDate: TDateTime): word;
var
d: TDateTime;
year, month, day: word;
begin
DecodeDate(TheDate, year, month, day); {use the current year}
d := EncodeDate(year, 1, 1);
result := trunc(TheDate - d) + 1;
end;