# Board index » delphi » Number of days between two dates?

## Number of days between two dates?

I would like to calculate the number of days between two dates.
The dates is from 1990 and on.
Are there any units/code already written?
JS

## Re:Number of days between two dates?

here're informations..

31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 28 31 30 31 30 31 31 30 31 30 31
31 29 31 30 31 30 31 31 30 31 30 31

and, remember, 4 years can be count as 1461 days.

##### Quote
James Stuart <james...@hotmail.com> wrote in message

news:37FFCF92.44E31EC6@hotmail.com...
##### Quote
> I would like to calculate the number of days between two dates.
> The dates is from 1990 and on.
> Are there any units/code already written?
> JS

## Re:Number of days between two dates?

##### Quote
>I would like to calculate the number of days between two dates.
>The dates is from 1990 and on.
>Are there any units/code already written?
>JS

You are lucky, I've done a unit for precisely that.It also gives you the
ability to know what's the day of the week for a particular date.
I'm pasting it.

----------------------------------------------------------------------------
---------------------------------------------------------------
Unit Dates;
{Author: Jose Santos <jcsan...@iname.com>}

Interface

Type
TSmallInteger = Integer;
TLongInteger  = Longint;

TDate=Record
Year  : TSmallInteger;
Month : TSmallInteger;
Day   : TSmallInteger;
End;

Const
RefDate: TDate=
(
Year  :  1000;
Month :     1;
Day   :     5
); {Reference date.It was a Sunday}

Function Bissext(Year: TSmallInteger): Boolean;
Function DaysInMonth(Year, Month: TSmallInteger): TLongInteger;
Function DaysFromDateXToY(DateX, DateY: TDate): TLongInteger;
Function DayOfWeek(Date: TDate): TSmallInteger;

Implementation

Function Bissext(Year: TSmallInteger): Boolean;
Begin
Bissext:=(Year Mod 4=0)And(Year Mod 100>0)Or(Year Mod 400=0);
End;

Function DaysInMonth(Year, Month: TSmallInteger): TLongInteger;
Begin
If Month In [1,3,5,7,8,10,12] Then
DaysInMonth:=31 Else
If Month <> 2 Then
DaysInMonth:=30 Else
If Bissext(Year) Then
DaysInMonth:=29 Else
DaysInMonth:=28;
End;

Function DaysFromYearXToY(YearX, YearY: TSmallInteger): TLongInteger;
Var
ResTemp: TLongInteger;
i: TSmallInteger;
Begin
ResTemp:=0;
For i:=YearX To YearY Do
If Bissext(i) Then
ResTemp:=ResTemp+366 Else
ResTemp:=ResTemp+365;
DaysFromYearXToY:=ResTemp;
End;

Function DaysFromMonthXToY(Year, MonthX, MonthY: TSmallInteger):
TLongInteger;
Var
ResTemp: TLongInteger;
i: TSmallInteger;
Begin
ResTemp:=0;
For i:=MonthX To MonthY Do
ResTemp:=ResTemp+DaysInMonth(Year, i);
DaysFromMonthXToY:=ResTemp;
End;

Function DaysFromDateXToY(DateX, DateY: TDate): TLongInteger;
Var
ResTemp: TLongInteger;
Begin
If DateX.Year<>DateY.Year Then
ResTemp:=DaysInMonth(DateX.Year, DateX.Month)-DateX.Day+
DaysFromMonthXToY(DateX.Year, DateX.Month+1, 12)+
DaysFromYearXToY(DateX.Year+1, DateY.Year-1)+
DaysFromMonthXToY(DateY.Year, 1, DateY.Month-1)+
DateY.Day Else
If DateX.Month<>DateY.Month Then
ResTemp:=DaysInMonth(DateX.Year, DateX.Month)-DateX.Day+
DaysFromMonthXToY(DateX.Year, DateX.Month+1, DateY.Month-1)+
DateY.Day Else
ResTemp:=DateY.Day-DateX.Day;
DaysFromDateXToY:=ResTemp;
End;

Function DayOfWeek(Date: TDate): TSmallInteger;
{Returns the day of week.0 is for Sunday, 1 for Monday, etc}
Begin
DayOfWeek:=DaysFromDateXToY(RefDate, Date) Mod 7;
End;

Begin
{No initialization required}
End.

----------------------------------------------------------------------------
-----------------------------------------------------------

You can also easily do a calendar with this unit.But avoid using DayOfWeek
to calculate every day of the month.It takes time and is unnecessary.You
just need to know the first day of the month.
RefDate is only used to calculate weekdays.It's unnecessary if you won't use
DayOfWeek.

Hope this is useful.

Regards,

Jose Santos

## Re:Number of days between two dates?

##### Quote
James Stuart wrote:
>I would like to calculate the number of days between two dates.
>The dates is from 1990 and on.
>Are there any units/code already written?
>JS

There is a thing like "Julian Date", used by astronomers.
They use it instead of a "normal" date (day, month, year).
JD is the number of days since 1st January 4712 B.C.
Having a procedure converting "normal" dates to JD
and reverse makes your problem easy to solve.
If you like, download my very old program containing
such a procedure (RokMD, DataJD). Unfortunately (for you)
it's commented in Polish. But look for these two procedure
(RokMD and DataJD) and I think you'll understand how to use
them.

A program calculating the position of Sun and Moon
(DOS, with source (TPascal) and these two procedures):
http://nest.sikornik.gliwice.pl/~piotrcf/eclip/sky.zip

Other programs:

Sun and Moon: when do they rise and set (DOS):
http://nest.sikornik.gliwice.pl/~piotrcf/eclip/sunr4.zip

Sun and Moon: when do they rise and set (Windows 9x),
also sundials for one day (northern hemisphere):
http://nest.sikornik.gliwice.pl/~piotrcf/eclip/sunr5.exe

Calendars (Windows 9x, Polish version):
http://nest.sikornik.gliwice.pl/~piotrcf/eclip/kalen.exe

PF

## Re:Number of days between two dates?

##### Quote
In article <7tq92f\$qp...@zeus.polsl.gliwice.pl>, PiotrCF <P...@who.net> wrote:

>James Stuart wrote:
>>I would like to calculate the number of days between two dates.
>>The dates is from 1990 and on.
>>Are there any units/code already written?
>>JS

>There is a thing like "Julian Date", used by astronomers.
>They use it instead of a "normal" date (day, month, year).
>JD is the number of days since 1st January 4712 B.C.
>Having a procedure converting "normal" dates to JD
>and reverse makes your problem easy to solve.

Julian dates are overly complicated thing as they change on noon and are
dependent on time zone. In fact one does not have to care what base
one uses.

Function Mul365(x:word):longint;
inline(
\$58/              {POP     AX}
\$BB/\$6d/1/        {MOV     BX,365}
\$F7/\$E3           {MUL     BX}
);

Function Div365(x:longint):word;
inline(
\$58/              {POP     AX}
\$5A/              {POP     DX}
\$BB/\$6d/1/        {MOV     BX,365}
\$F7/\$F3           {DIV     BX}
);

const Dbfmlut:array[boolean,1..12] of word=
((0,31,59,90,120,151,181,212,243,273,304,334),
(0,31,60,91,121,152,182,213,244,274,305,335));

Function DateNro(y,m,d:integer):longint;
begin
DateNro:=d+dbfmLut[(y and 3=0) and
((y mod 100>0) or (y mod 400=0)),m]
+(y-1) div 4-(y-1) div 100+(y-1) div 400-1
+mul365(y-1)
End;

{\$b-}
Procedure Date(nro:longint; var y,m,d:integer);
var dl:integer;
leap:boolean;
Begin
y:=Div365(nro)+1;
dl:=nro-mul365(y)-(y div 4-y div 100+y div 400);
inc(y);
repeat
dec(y);
leap:=(y and 3=0) and ((y mod 100>0) or (y mod 400=0));
inc(dl,365+ord(leap));
until dl>=0;

m:=word(dl) div 32+1;
if (m<12) and (dl>=Dbfmlut[leap,m+1]) then inc(m);
d:=dl-dbfmlut[leap,m]+1;
End;

Function WeekDay(nro:longint):word; { 0: Su, 6: Sa }
begin
Weekday:=(nro+1) mod 7;
End;

Osmo

## Re:Number of days between two dates?

PiotrCF wrote:

[...]

##### Quote
> A program calculating the position of Sun and Moon
> (DOS, with source (TPascal) and these two procedures):
> http://nest.sikornik.gliwice.pl/~piotrcf/eclip/sky.zip
> Other programs:
> Sun and Moon: when do they rise and set (DOS):
> http://nest.sikornik.gliwice.pl/~piotrcf/eclip/sunr4.zip

[snip Win98 stuff]

Thank You! These are going to be very useful.

Best Regards,

Michael R. Monett
mailto:m_mon...@hotmail.com

## Re:Number of days between two dates?

JRS:  In article <7tq92f\$qp...@zeus.polsl.gliwice.pl> of Sun, 10 Oct
1999 16:49:42 in news:comp.lang.pascal.borland, PiotrCF <P...@who.net>
wrote:

##### Quote

>James Stuart wrote:
>>I would like to calculate the number of days between two dates.
>>The dates is from 1990 and on.
>>Are there any units/code already written?
>>JS

>There is a thing like "Julian Date", used by astronomers.
>They use it instead of a "normal" date (day, month, year).
>JD is the number of days since 1st January 4712 B.C.
>Having a procedure converting "normal" dates to JD
>and reverse makes your problem easy to solve.
>If you like, download my very old program containing
>such a procedure (RokMD, DataJD). Unfortunately (for you)
>it's commented in Polish. But look for these two procedure
>(RokMD and DataJD) and I think you'll understand how to use
>them.

Not 100% accurate.  JD is the number of days since noon GMT on 1st Jan
4713 (4713 sic) BC.  IMHO it is better to use Modified Julian Date, MJD
= JD-2400000.5, to avoid this, and to make the numbers smaller (pretend
you're at Greenwich).

<URL: http://www.merlyn.demon.co.uk/programs/dateprox.pas> has code;
<URL: http://www.merlyn.demon.co.uk/programs/mjd_date.pas> tests it;
<URL: http://www.merlyn.demon.co.uk/programs/version.pas> needed;
TP7/BP7/D3 compatible.

The routines are sufficiently fast; but since they are programmed from
first principles in am attempt to be obviously correct, they may be a
little slower than those of others; in which case use them for
verification.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
Web <URL: http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS, EXE in <URL: http://www.merlyn.demon.co.uk/programs/> - see 00index.txt.
Do not Mail News to me.    Before a reply, quote with ">" or "> " (SoRFC1036)

## Re:Number of days between two dates?

##### Quote
Dr John Stockton wrote:
>Not 100% accurate.  JD is the number of days since noon GMT on 1st Jan
>4713 (4713 sic) BC.

My mistake. 4713, not 4712 - sorry.

##### Quote
>IMHO it is better to use Modified Julian Date, MJD
>= JD-2400000.5, to avoid this, and to make the numbers smaller (pretend
>you're at Greenwich).

But it makes your procedures "incopatible" with normal JD.
Most computers don't have problems dealing with numbers
like 2500000.

##### Quote

><URL: http://www.merlyn.demon.co.uk/programs/dateprox.pas> has code;
><URL: http://www.merlyn.demon.co.uk/programs/mjd_date.pas> tests it;
><URL: http://www.merlyn.demon.co.uk/programs/version.pas> needed;
>TP7/BP7/D3 compatible.

>The routines are sufficiently fast; but since they are programmed from
>first principles in am attempt to be obviously correct, they may be a
>little slower than those of others; in which case use them for
>verification.

I have found another formulas. They seem a bit "mysterious",
but they work and are very short. Take a look at them:

Converting "normal" date to JD (r: year, m: month, d: day):
===========================================

var dt: integer;   {a global variable: day of week }

function DataJD(r,m,d:real):real;
var a,b,c,e:real;
begin
if r<0 then r:=r+1;
a:=4716+r+int((m+9)/12);
b:=1729279.5+367*r+int(275*m/9)-int(7*a/4)+d;
c:=int((a+83)/100);
e:=int(3*(c+1)/4);
a:=b+38-e;
if a<2299160.5 then a:=b;
DataJD:=a;
dt:=round(a+1.1-7*int((a+1.1)/7));
while dt<0 do dt:=dt+7
end;

An auxiliary function (sorry, I don't remember the reason
why isn't it a simple int):

FUNCTION Int1(x:REAL):REAL;
BEGIN
IF x>=0 THEN Int1:=int(x)
ELSE
IF x=int(x) THEN Int1:=x ELSE Int1:=int(x)-1
END;

Converting a JD to (year, month, day, hour):
===================================

PROCEDURE RokMD(jd: REAL; VAR r,m,d:INTEGER; VAR gr:REAL);
VAR w,x,u,z,y,a,b,c,e,f:REAL;
BEGIN
gr:=jd-int1(jd-0.5)-0.5;
w:=int(jd+0.5)+0.5; x:=int(w); u:=w-x;
y:=int((x+32044.5)/36524.25); z:=x+y-int(y/4)-38;
IF jd<2299160.5 THEN z:=x;
a:=z+1524; b:=int((a-122.1)/365.25); c:=a-365*b-int(b/4);
e:=int(c/30.61);
f:=int(e/14);
r:=round(b-4716+f); m:=round(e-1-12*f); d:=trunc(c+u-int(153*e/5)-0.5);
IF r<=0 THEN r:=pred(r);
dt:=round(jd+1.1-7*int((jd+1.1)/7));
WHILE dt<0 DO dt:=dt+7
END;

Regards
Piotr
Gliwice, Poland

## Re:Number of days between two dates?

JRS:  In article <7tt1sq\$9n...@zeus.polsl.gliwice.pl> of Mon, 11 Oct
1999 18:05:17 in news:comp.lang.pascal.borland, PiotrCF <P...@who.net>
wrote:

##### Quote
>Dr John Stockton wrote:
>>IMHO it is better to use Modified Julian Date, MJD
>>= JD-2400000.5, to avoid this, and to make the numbers smaller (pretend
>>you're at Greenwich).

>But it makes your procedures "incopatible" with normal JD.
>Most computers don't have problems dealing with numbers
>like 2500000.

No, but people do; I prefer to avoid the half-day errors, and I am told
that in practice the use of MJD is common.  Certainly my colleagues used
it.  But it is a matter of opinion.  MJD has the advantage that there
were no "funnies" in the calendar (in most "Christian" countries bar
Russia) between then and now.

##### Quote
>><URL: http://www.merlyn.demon.co.uk/programs/dateprox.pas> has code;
>><URL: http://www.merlyn.demon.co.uk/programs/mjd_date.pas> tests it;
>><URL: http://www.merlyn.demon.co.uk/programs/version.pas> needed;
>>TP7/BP7/D3 compatible.

>>The routines are sufficiently fast; but since they are programmed from
>>first principles in am attempt to be obviously correct, they may be a
>>little slower than those of others; in which case use them for
>>verification.

>I have found another formulas. They seem a bit "mysterious",
>but they work and are very short. Take a look at them:
> ...

As you say, they are partly mysterious.  This is essentially an integer
problem & I prefer an integer solution.  Nowadays the FPU of a PC is
fast; but it's unlikely to make much difference to the overall speed.  I
think I still understand my code, and I recall no outstanding comments
from anyone who cannot!  There are many ways of getting the right

##### Quote
>An auxiliary function (sorry, I don't remember the reason
>why isn't it a simple int):

>FUNCTION Int1(x:REAL):REAL;
>BEGIN
>  IF x>=0 THEN Int1:=int(x)
>    ELSE
>  IF x=int(x) THEN Int1:=x ELSE Int1:=int(x)-1
>END;

I expect it will be because the logic requires truncation towards minus
infinity and the standard function truncates towards zero.  There is a
similar annoyance with MOD & DIV.  In longcalc.pas, the MOD & DIV
operators are rationally defined across zero, and code using them is
simpler.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
Web <URL: http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS, EXE in <URL: http://www.merlyn.demon.co.uk/programs/> - see 00index.txt.
Do not Mail News to me.    Before a reply, quote with ">" or "> " (SoRFC1036)