Calculate date without counting weekends and holidays

Asked

Viewed 175 times

1

I’m needing to calculate future dates through a number of days, but you should not count the weekends and holidays.

Take the example: The project starts on 01/01/2020 and lasts 25 days, that is, it has to end on 29/01/2020 (skipping the weekends and the holiday of January 1).

I made a if with IncDay but it just skipped the first weekend, I mean, I have no idea where to start to solve this problem.

Follow the code I’ve made so far:

    procedure TformPrincipal.QueryProjItemCalcFields(DataSet: TDataSet);
var
    dtFim: TDateTime;
    dtSemFds: TDateTime;
begin

    //zerar os campos se a duração tiver vazia
    if QueryProjItemprojitem_duracao.Value=0
    then
        begin
            QueryProjItemvlcustorecurso.AsFloat:=0;
        end
    else
        begin
            //Calcula a data de acordo com a duração sem FDS
            dtFim:=(QueryProjItemprojitem_dt_inicio.AsDateTime + QueryProjItemprojitem_duracao.AsInteger);

            if DayOfWeek(dtFim)=1 then
                    dtFim:= incDay(dtFim,1)
                else
                if DayOfWeek(dtFim)=7 then
                    dtFim:= incDay(dtFim,2);

            QueryProjItemdtFinal.AsDateTime :=dtFim;


            //Calcula o valor total dos recursos de acordo com a duração
            QueryProjItemvlcustorecurso.AsFloat:=
            QueryProjItemrec_vl.AsFloat * QueryProjItemprojitem_duracao.AsInteger;


        end;

end;
  • Hello Felipe, post the code and point out what error or difficulty is finding.

  • Hello all right? I edited the post and made the inclusion of the code, thank you

  • You need to have the holidays registered somewhere, because they vary a lot: are they holidays from which country? If it is in Brazil, has also state and municipal holidays, will be taken into account? Have the mobile holidays, like Easter and Carnival, which changes every year. Anyway, you only made one if, but I really should have made a loop and increase the date N times (and if, add a condition checking if the date is in this register of holidays). I don’t program in Delphi so I’m not going to risk an answer, but in broad lines that’s it...

  • @hkotsubo thanks for the tip... So if I did just "skip the weekend of the sequel" and this really isn’t functional for me. Could you show an example of a loop that looks like this? It could just be the same logic, because that’s what I’m having difficulties with, depending on it might help me a lot. The holidays I will do in a separate table with manual inclusion even. Thank you very much

  • That would be more or less: https://ideone.com/E3ohLx (code in "portugol") - I have not tested this algorithm in any language, it may need some adjustment

  • 1

    @hkotsubo I am very grateful for your help, based on the logic that made available I developed a code that worked perfectly for my project.

Show 1 more comment

1 answer

0


Following the @hkotsubo tip, I developed the following code that solved my problem:

procedure TformPrincipal.QueryProjItemCalcFields(DataSet: TDataSet);
var
dtFim: TDateTime;
duracao: Integer;
begin
//zerar os campos se a duração tiver vazia
if QueryProjItemprojitem_duracao.Value=0
then
    begin
        QueryProjItemvlcustorecurso.AsFloat:=0;
    end
else
    begin
        dtFim:=QueryProjItemprojitem_dt_inicio.AsDateTime;
        duracao:=2;
        while duracao <= QueryProjItemprojitem_duracao.AsInteger do
        begin
               dtFim:= IncDay(dtFim,1);
                while (DayOfWeek(dtFim)=1) or (DayOfWeek(dtFim)=7) do
                begin
                    if DayOfWeek(dtFim)=1 then
                        dtFim:= IncDay(dtFim,1);
                    if DayOfWeek(dtFim)=7 then
                        dtFim:=IncDay(dtFim,2);
                end;
             duracao:=duracao + 1;
        end;
        QueryProjItemdtFinal.AsDateTime :=dtFim;

        //Calcula o valor total dos recursos de acordo com a duração
        QueryProjItemvlcustorecurso.AsFloat:=
        QueryProjItemrec_vl.AsFloat * 
        QueryProjItemprojitem_duracao.AsInteger;


    end;

end;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.