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?


Quote
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
answer.

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)

Other Threads