Разница между двумя датами в Паскале

Эта программа должна находить разницу между двумя датами, но у нее есть ошибка, и я не могу ее найти. Он продолжает возвращать большое число - пожалуйста, помогите

Program tp4;
Type
  dt = Record
    jour : Integer;
    mois : Integer;
    annee : Integer;
  End;
Var
  date : dt ;
  y,x,i,s : Integer;
Begin
  x := 0;
  s := 0;
  For y:=1 To 2 Do                                                  
    //2 dates
    Begin
      Writeln('Entrez un date : jour mois année ');
      Readln( date.jour, date.mois, date.annee);
      While ((date.jour<=0) Or (date.jour>31) Or (date.mois>12) Or (date.annee<=0) ) Do
        //verfication loop
        Begin
          Writeln('Entrez une  date valide : jour mois année ');
          Readln(date.jour ,date.mois ,date.annee);
        End;
      s := s+date.jour  ;
      For i:= 1 To date.mois-1 Do
        Case i Of
          3,5,7,8,10,12,1 : s := s+31;
          4,6,9,11 : s := s +30;
          2 : If ((date.annee Mod 100)=0) And ((date.annee Mod 400) = 0 ) Then //convert months to days
                s := s+29
              Else If date.annee Mod 4 = 0 Then
                     s := s+29
              Else s := s+28;
        End;                                                                                                                            //Convert years to days
      For i:= 1 To date.annee  Do
            
            If (i Mod 100 = 0) And (i Mod 400 = 0) Then s := s+366
            Else If (i Mod 4 =0) Then s := s+366
            Else s := s+365;
                    x:=s-x ; 
                
    End;

        
  If (x)<=0 Then
    Writeln('la difference est :',-x)
  Else Writeln('la difference est :',x);
  Readln;
End.

**input**
12 03 2019

13 03 2019
**output**


737510

person M4hf0d    schedule 14.02.2021    source источник


Ответы (3)


Вы используете цикл For y ... для запроса ввода и расчета количества дней для каждого ввода. Внутри цикла переменная s является счетчиком дней.

Ошибка заключается в том, что вы обнуляете s перед циклом For y ..., а не в начале цикла. Поэтому, когда вы запрашиваете дату во второй раз, s по-прежнему имеет значение из первой даты, поверх которой вы затем начинаете вычислять дни для второй даты.

Исправление, конечно же, заключается в перемещении s := 0; в начало цикла For y ...,

или измените первое назначение s с

s := s + date.jour;

to

s := date.jour;
person Tom Brunberg    schedule 15.02.2021

Думаю ошибка была где-то в s и x (x:=s-x; и т.д.), сделал рефакторинг:

Program tp4;

Type dt = Record 
  jour : Integer;
  mois : Integer;
  annee : Integer;
End;

Type
  arrayDate = array[1..2] of dt;

Var
  y,i,f,s : Integer;
  arrDate: arrayDate;

function Leap (Y : Word): Boolean;
Begin
  If (Y Mod 4) <> 0 Then Leap := FALSE 
  Else If (Y Mod 100) <> 0 Then Leap := TRUE 
  Else Leap := (Y Mod 400) = 0;
End;

function Lenght (date: dt) : Integer;
Begin
  Lenght := 0;
  Lenght := Lenght + date.jour;
  For i := 1 To date.mois Do 
    Case i Of 
      3, 5, 7, 8, 10, 12, 1 : Lenght := Lenght + 31;
      4, 6, 9, 11 : Lenght := Lenght + 30;
      2 : If Leap (date.annee) Then Lenght := Lenght + 29 Else Lenght:= Lenght + 28;
    End;  
  For i := 1 To date.annee Do  //Convert years to days
    If Leap (i) Then Lenght := Lenght + 366 Else Lenght := Lenght + 365;
End;

Begin
  For y := 1 To 2 Do  //2 dates
  Begin Writeln ('Entrez un date : jour mois année ');
    Readln (arrDate[y].jour, arrDate[y].mois, arrDate[y].annee);
    While ((arrDate[y].jour <= 0) 
      Or (arrDate[y].jour > 31) 
      Or (arrDate[y].mois > 12) 
      Or (arrDate[y].annee <= 0)) Do //verfication loop
    Begin
      Writeln ('Entrez une  date valide : jour mois année ');
      Readln (arrDate[y].jour, arrDate[y].mois, arrDate[y].annee);
    End;
  End;
  
  f := Lenght(arrDate[1]);
  s := Lenght(arrDate[2]);

  Writeln ('la difference est :', Abs(s - f)); // absolute |s-f|
  Readln;
End.
person Daniil Loban    schedule 14.02.2021

Нахождение разницы между двумя датами, отстоящими друг от друга на 6000 лет, в цикле? И (ab) используя имя стандартной функции Length? Ой!

Попробуй это:

//----------------------------------------------------------------------
// Convert a date to its Julian Day Number
//----------------------------------------------------------------------
procedure cj(dd, mm, yyyy: longint; var jdn, dow: longint);
var
  cj_y,
  cj_c,
  cj_x,
  cj_y: double;

begin
  if dd = 0 then
    begin
      jdn:= -1
      dow:= -1;
    end
  else
    begin
      cj_y:= yyyy + (mm - 2.85) / 12;
      cj_c:= 0.75 * trunc(cj_y * 0.01);

      cj_x:= frac(cj_y);
      cj_y:= trunc(cj_y);

      jdn:= trunc(
            trunc(
            trunc(367 * cj_x) + 367 * (cj_y) -
                                1.75 * cj_y + dd) - cj_c) +
                                1721115.0;
      dow:= jdn mod 7;
    end;
end; {cj}

Приведенная формула действительна для дней после 15.10.1582, небольшая поправка позволит датировать даты, восходящие к 01.03.00.

Перейдите по ссылке в https://groups.google.com/g/comp.lang.pascal.borland/c/itwgcfYpLEU, который я разместил в августе 1998 года в comp.lang.pascal.borland для пояснений.

person prino    schedule 17.04.2021