iki tarih arasındaki çalışma gün sayısı

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
TURGUT
Üye
Mesajlar: 54
Kayıt: 27 May 2005 03:19
Konum: ANKARA/ETİMESGUT

iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen TURGUT »

İki tarih arasındaki çalışma gün sayısını bulmak istiyorum. Resmi tatiler(Dini ve Milli) ve haftasonuna göre kontrol edecek aradaki çalışma gün sayısını döndürecek kodlara ihtiyacım var. Nasıl bir yol izlemeliyim. dini tatiller her sene farklı günlere denk geldiğinden bunun için form üzerinden mi tarih aralığını vermek mi mantıklı veya bunun için fonksiyonlar var mı.Yardımlarınıza ihtiyacım var.

İyi çalışmalar;
Kullanıcı avatarı
White Rose
Üye
Mesajlar: 726
Kayıt: 06 Tem 2005 09:41
Konum: Güneyden
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen White Rose »

Dini tatiller için Alperen Namaz Vakitleri programına ait dll dosyası var googleden aratırsanız bulursunuz sanırım. O dll dosyasını kullanarak dini günleri bulabilirsiniz. Belki bu formdada olabilri arama yaptırın.

yada aşağıdaki linkten programı indirin onun içinde dll dosyası var.

http://rapidshare.com/files/18381507/Ez ... z.rar.html
TURGUT
Üye
Mesajlar: 54
Kayıt: 27 May 2005 03:19
Konum: ANKARA/ETİMESGUT

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen TURGUT »

Teşekkür ederim dini tatil günlerini formdan giriş yapmak yerine dll dosyasından almak daha doğru olacak. Çalışma gün sayısını hesaplatabileceğim kodlara ihtiyacım var.
mkysoft
Kıdemli Üye
Mesajlar: 3110
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen mkysoft »

Bakanlar kurulu karar alarak calisma gununu tatil edebiliyor. Sizde biliyorsunuz ki bazen bayramlara gun ekleniyor. Bu nedenle kesin bir kurali yok. Veri tabaninda tutarak kullanicilarin yeni tatil ekleyebilmesini saglayabilirsiniz.
Kullanıcı avatarı
White Rose
Üye
Mesajlar: 726
Kayıt: 06 Tem 2005 09:41
Konum: Güneyden
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen White Rose »

öncelikle standart tatil günlerini gireceğiniz ve üzerinde değişiklik yapabileceğiniz bir dosyanız olmalı.
sonra belirlediğiniz başlama tarihinden yine belirlediğiniz bitiş tarihine kadar for döngüsü ile günü bir artırarak
tek tek günlerin tatil gününe denk gelip gelmediğini kontrol ettirerek yapabilirsiniz.

//uses kısmına dateutils eklemeyi unutmayın...

procedure Tform1.button1click(sender.tobject);
var
t1,t2:Tdate;
Gun,I:Integer;
begin
t1:=datetimepicker1.Date;
t2:=datetimepicker2.Date;

Gun:=daysbetween(t2,t1); // iki tarih arası gün farkı
Lbl_Fark.Caption:=inttostr(Gun);

FOR I:=1 To Gun do begin
if t1=tatiltarihi then begin
// yapacağınız işlemler...
end;
IncDay(t1); tarihi bir gün artır
end;
cecihan
Üye
Mesajlar: 94
Kayıt: 30 Ara 2006 11:40
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen cecihan »

Zannediyorum bu kodları yine bu forumda bulmuştum, oldukçada kullanışlı. c++ versionu bendeki ama forumda delphi kodlamasıda (herhalde) vardı.

bool Tatilmi(TDateTime Tarih)
{
AnsiString Tatil[5]={"01.01","23.04","19.05","30.08","29.10"};
int i;

if(Tarih.DayOfWeek()==1 || Tarih.DayOfWeek()==7) return true;
for(i=0;i<5;i++)
if(Tarih==StrToDate( Tatil+FormatDateTime(".YYYY",Date()) )) return true;
return false;
}
//---------------------------------------------------------------------------
TDateTime IsGunuEkle(TDateTime Tarih,int Gun)
{
int i;

i=0;
while(i<Gun)
{
Tarih=Tarih+1;
if(!Tatilmi(Tarih)) i++;
}
return Tarih;
}
TURGUT
Üye
Mesajlar: 54
Kayıt: 27 May 2005 03:19
Konum: ANKARA/ETİMESGUT

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen TURGUT »

Kod: Tümünü seç

procedure TForm6.Query1CalcFields(DataSet: TDataSet);
var
t1,t2:Tdate;
Gun,I,calisma:Integer;
begin

t1:=query1otarih.AsDateTime; // 02.02.2010 onay tarihi
t2:=query1btarih.AsDateTime; //24.02.2010 bitiş tarihi
Gun:=daysbetween(t2,t1); // iki tarih arası gün farkı
calisma:=0;
FOR I:=1 To gun do   // 22
begin
    if  (dayofweek(t1)<>1) or (dayofweek(t1)<>7)  then
    begin
    calisma:=calisma+1;
    end;

IncDay(t1);
end;
query1gun.value:=calisma;
end;
end.
yukarıdaki kodda veritabanından 02.02.2010 ve 24.02.2010 tarihli kaydı örnek gösterdim burda gun farkı 22 fakat 6 günü haftasonuna denk geliyor. Hesaplaması gereken 16gün. Ancak herseferinde if li döngüye giriyor ve günü 22 gösteriyor. Sanırım mantık hatası yapıyorum ama bulamadım.
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen Lost Soul »

if (dayofweek(t1)<>1) or (dayofweek(t1)<>7) then

yerine

if (dayofweek(t1)<>1) and (dayofweek(t1)<>7) then
yazmanız gerekiyor.
TURGUT
Üye
Mesajlar: 54
Kayıt: 27 May 2005 03:19
Konum: ANKARA/ETİMESGUT

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen TURGUT »

if (dayofweek(t1)<>1) and (dayofweek(t1)<>7) then
t1 tarihi iki şartı birden sağlamaz. ya cumartesiye denk gelir veya pazara. kodda t2 ile t1 arası gün farkını alıp t1 den sonra o fark kadar tarihi artırıyor. bu arada haftasonuna gelen tarihleri saymamasını gerekiyor. Birde buraya resmi tatilleri veri tabanından kontrol eden döngü bloğu eklemem lazım resmi tatillere gelen günleri de saymamısı lazım.(query2.eof) bu bloğu nereye eklemem lazım. For döngüsünün içinde her bir tarih için hem haftasonuna denk geliyormu hemde resmi tatillere denk geliyormu kontrol ettirmem lazım.
While not query2.eof do ile denedim fakat başarılı olamadım.

Kodlara bide siz göz atarmısınız.

Kod: Tümünü seç

procedure TForm6.Query1CalcFields(DataSet: TDataSet);
var
t1,t2:Tdate;
Gun,I,calisma:Integer;
begin

t1:=query1otarih.AsDateTime; // 02.02.2010 onay tarihi
t2:=query1btarih.AsDateTime; //24.02.2010 bitiş tarihi
Gun:=daysbetween(t2,t1); // iki tarih arası gün farkı
calisma:=0;
FOR I:=1 To gun do   // 22
begin
    if  (dayofweek(t1)<>1) or (dayofweek(t1)<>7)  then
    begin
    calisma:=calisma+1;
    end;

IncDay(t1);
end;
query1gun.value:=calisma;
end;
end.
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen aslangeri »

s.a.
öncelikle bir fonksiyon hazırla tarih tipinde bir parametresi olan, geriye true yada false döndüren

Kod: Tümünü seç

Function TatilGunumu(aTarih:TDate):Boolean
Begin
//.... buraya kontrol kriterlerini koy tatilgünü ise true değilse false  dönder
End;
daha sonra hazırladığın döngünün içinde bu fonksiyonu çağır.

Kod: Tümünü seç

FOR I:=1 To gun do   // 22
begin
   if TatilGunumu(t1)=False then
    begin
    calisma:=calisma+1;
    end;
IncDay(t1);
end;
geriye tatilgünümü metodunun içeriğini doldurmak kalıyor ki onu yapacağına eminim.
kolay gelsin.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen Lost Soul »

Kod: Tümünü seç

if  (dayofweek(t1)<>1) or (dayofweek(t1)<>7)  then
dediğiniz zaman eğer cumartesi ise
or dan dolayı cumartesi olabilir ama pazar değil ki diyip gene true döndürecektir.
keza pazar olsa dahi bugün pazar olabilir ama sonuşöta cumartesi değil diyip gene true döndürür.
haliyle haftanın 7 gününü de sayar

fakat

Kod: Tümünü seç

if  (dayofweek(t1)<>1) and (dayofweek(t1)<>7)  then
ise eğer hem cumartesi hem de pazar değilse diyor



kodu denediniz mi :?: :!:


neyse
aşağıdaki kodu şimdi yazdım ilerde bana da lazım olur diye.

Kod: Tümünü seç

{ DayOfWeek returns the day of the week of the given date. The result is an
  integer between 1 and 7, corresponding to Sunday through Saturday.
  This function is not ISO 8601 compliant, for that see the DateUtils unit. }

Function CalismaGunleriSayisi (Baslangic,Bitis : TDateTime;
                         OzelGunler:Array of TDateTime):Integer;
const
  Gunler : array[1..7] of Integer = (7,1,2,3,4,5,6);
var
  tmpTarih : TDateTime;
  iTemp : Integer;
  inDate : Boolean;
Begin
  Result :=0;
  tmpTarih:=Min(Baslangic,Bitis);
  while tmpTarih<=Max(Baslangic,Bitis) do
  Begin
    if not (Gunler[DayOfWeek(tmpTarih)] in [DaySaturday,DaySunday]) then
    Begin
      if Length(OzelGunler)=0 then Inc(Result)
      else
      Begin
        inDate := False;
        for iTemp := Low(OzelGunler) to High(OzelGunler) do
        Begin
          if tmpTarih=OzelGunler[iTemp] then
          Begin
            inDate:=True;
            Break;
          End;
        End;
        if not inDate then inc(Result);
      End;
    End;
    tmpTarih := IncDay(tmpTarih,1);
  End;
End;
özel gün olmadan kullanımı

Kod: Tümünü seç

  ShowMessage(
    InttoStr(
      CalismaGunleriSayisi(StrToDate('01.04.2010'),StrToDate('30.04.2010'),[])
            )
             );
Sonuç : 22


Özel Günle kullanımı "23 Nisan"

Kod: Tümünü seç

  ShowMessage(
    InttoStr(
      CalismaGunleriSayisi(StrToDate('01.04.2010'),StrToDate('30.04.2010'),
      [StrToDate('23.04.2010')])
            )
             );

Sonuç 21.

ve bu da bu yılki çalışma günü

Kod: Tümünü seç

  ShowMessage
  (
    InttoStr
      (
        CalismaGunleriSayisi(StrToDate('01.01.2010'),StrToDate('31.12.2010'),
        [
          StrToDate('23.04.2010'),
          StrToDate('01.01.2010'),
          StrToDate('23.04.2010'),
          StrToDate('01.05.2010'),
          StrToDate('19.05.2010'),
          StrToDate('30.08.2010'),
          StrToDate('09.09.2010'),
          StrToDate('10.09.2010'),
          StrToDate('11.09.2010'),
          StrToDate('29.10.2010'),
          StrToDate('16.11.2010'),
          StrToDate('17.11.2010'),
          StrToDate('18.11.2010'),
          StrToDate('19.11.2010')

      ])

            )
             );

Sonuç 250
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen aslangeri »

s.a.
özel günler için oluşturduğunuz dizide yılalrı belirtmeden sadece ay ve günleri belirtip yılı aktif yıldan kontrol ettirerek kodu hersene güncelleme zahmetinden kurtulabilirsiniz.
:wink:
kolay gelsin.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
conari
Üye
Mesajlar: 2102
Kayıt: 27 Nis 2006 03:10
Konum: İstanbul & Gebze Karışık

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen conari »

StrToDate('23.04.2010') İki kere verilmiş. :mrgreen:

bayramlar değişiyor. ayrıca kodu incelemedim ama resmi tatil hafta sonuna geliyor ise değerlendirmiyordur sanırım.
Bir kelimenin anlamını öğretsen bile yeter..
ResimResim
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen Lost Soul »

aslangeri yazdı:s.a.
özel günler için oluşturduğunuz dizide yılalrı belirtmeden sadece ay ve günleri belirtip yılı aktif yıldan kontrol ettirerek kodu hersene güncelleme zahmetinden kurtulabilirsiniz.
:wink:
kolay gelsin.
a.s. 03.10.2010 ile 07.03.2011 için düşünün. :)
conari yazdı: StrToDate('23.04.2010') İki kere verilmiş. :mrgreen:

bayramlar değişiyor. ayrıca kodu incelemedim ama resmi tatil hafta sonuna geliyor ise değerlendirmiyordur sanırım.
farketmiyor 15 tane 23 Nisan koysak ve hepsi cumartesiye gelse eksiltme değil şartları karşılayınca arttırma yapptığı için değilşen birşey olmuyor.

Not: Yarım günler eklenmedi tabi :D
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: iki tarih arasındaki çalışma gün sayısı

Mesaj gönderen Lost Soul »

bu arada delphinin kodlarını kurcalarken farkettim.
sysutils deki DayOfWeek de ilk gün 7 son gn 6 yani 7,1,2,3,4,5,6
dateutils deki DayOfTheWeek de ilk gün 1 son gün 7 yani 1,2,3,4,5,6,7
yani verdiğim koddaki DayOfWeek yerine DayOfTheWeek kullanırsak gunler isimli diziye gerek kalmayacak :)
fonksiyonun sağında {ISO 8601} açıklaması bulunan fonksiynlarda ilk gün 1 olarak belirlenmiş. diğerlerinde ise 7
gene dateutils deki
Const değerler ex:(DaySaturday,DaySunday,DayMonday) gibi değerler de ISO 8601 'e göre değerlenmiş.
yani ilk gün 1. son gün 7 olarak.
vesaire vesaire.
Cevapla