12
votes

Comment calculer le nombre de jours ouvrables entre deux dates?

Je dois calculer le nombre de jours ouvrables (jours ouvrables) entre deux dates données. Les jours ouvrables sont tous les jours de la semaine sauf samedi et dimanche. Je ne considère pas des vacances dans ce compte.

Comment calculer le nombre de jours ouvrables entre deux dates?


0 commentaires

3 Réponses :


9
votes

7 commentaires

Je vois merci ... Je n'ai pas besoin de vacances puisqu'elles n'affecteront pas de manière significative sur les délais de retournement .. mais les week-ends sont un problème. Je vais vous donner un coup de feu.


J'ai utilisé presque la même fonction..works super. Il y a aussi beaucoup aussi peut spécimen, si peu d'avoir un problème avec des vacances, ils n'affecteront pas l'ensemble.


Ce serait bien de le faire sans boucle.


@DavidHeffernan: +1. J'avais cela sur ma liste de faire juste pour le plaisir, mais Lu RD et User1008646 me battent. :)


Sardukar: Vous devriez changer votre réponse acceptée à l'une d'une personne postée par @lurd ou user1008648. Les deux sont considérablement plus rapides que ma solution. (User10008646 est légèrement plus rapide, mais IMO Lurd est plus facile à lire et à conserver plus tard.)


@Kenwhite a trouvé un bug ... "Alors que (le currate


@Johneasley: Oui, tu as raison. Édité pour réparer dans les deux cas. Merci.



12
votes

sans boucle tous les jours et les paramètres d'entrée ne dépendent pas de la commande.

Uses DateUtils,Math;

function WorkingDaysBetween( const firstDate,secondDate : TDateTime) : Integer;
var
  startDate,stopDate : TDateTime;
  startDow,stopDow : Integer;
begin
  if (firstDate < secondDate) then
  begin
    startDate := firstDate;
    stopDate := secondDate;
  end
  else
  begin
    startDate := secondDate;
    stopDate := firstDate;
  end; 
  startDow := DayOfTheWeek(startDate);
  stopDow := DayOfTheWeek(stopDate);
  if (stopDow >= startDow) then
    stopDow := Min(stopDow,6)
  else
    Inc(stopDow,5); 

  Result := 
    5*WeeksBetween(stopDate,startDate) + 
    (stopDow - Min(startDow,6));
end;


3 commentaires

+1. Joli! Je n'avais pas la chance de regarder une solution non-boucle - maintenant, je n'ai certainement pas besoin de le faire. :-)


Je reçois des résultats différents des deux autres, avec votre fonction, si je testez dt1: = maintenant et dt2: = incueil (maintenant 3) .


@kobik, merci. La fonction de numérotation de jour correcte est bien sûr Dayofthewek () .



13
votes
function BusinessDaysSinceFixedDate ( const nDate : tDateTime ) : integer;
const
  Map : array [ -6 .. 6 ] of integer
      = (  0, 0, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9 ); 
var
  X : integer;
begin
  X := trunc ( nDate );
  Result := 5 * ( X div 7 ) + Map [ X mod 7 ];
end;

function BusinessDaysBetweenDates ( const nStartDate : tDateTime;
                                    const nEndDate   : tDateTime ) : integer;
begin
  Result :=   BusinessDaysSinceFixedDate ( nEndDate )
            - BusinessDaysSinceFixedDate ( nStartDate );
end;
The routine BusinessDaysSinceFixedDate calculates the number of business days since a fixed date. The specific date, which is irrelevant, is Monday, 25 December, 1899.
It simply counts the number of weeks that have passed (X div 7) and multiplies that by 5. 
Then it adds an offset to correct based on the day of the week. 
Note that (X mod 7) will return a negative value for a negative date, i.e. a date before 30 December, 1899. The routine BusinessDaysBetweenDates simply calls BusinessDaysSinceFixedDate for the start and end date and subtracts one from the other. 

1 commentaires

+1. Vous pouvez ajouter ABS au résultat de dynamique d'entrepriseBetweendates (donc le résultat des jours sera toujours positif).