Arbeitstage berechnen  
Frank Dzaebel, erstellt am: 7.8.2006, zuletzt geändert:  7.8.2006
Kategorie: Implementation, .NET-Version: 2.0, [Download]

Eine sinnvolle Implementierung der Arbeitstage zwischen zwei bestimmten Tagen ist gar nicht so trivial. Hier eine mögliche Sichtweise, nebst Implementierung.

   Von   Bis    Arbeitstage Applikation
Mo 07.08.2006 Mo 07.08.2006 0
Mo 07.08.2006 Di 08.08.2006 1
Mo 07.08.2006 Mi 09.08.2006 2
Mo 07.08.2006 Do 10.08.2006 3
Mo 07.08.2006 Fr 11.08.2006 4
Mo 07.08.2006 Sa 12.08.2006 5
Mo 07.08.2006 So 13.08.2006 5
Mo 07.08.2006 Mo 14.08.2006 5
Mo 07.08.2006 Di 15.08.2006 6
Mo 07.08.2006 Mi 16.08.2006 7
Mo 07.08.2006 Do 17.08.2006 8
Mo 07.08.2006 Fr 18.08.2006 9
Mo 07.08.2006 Mo 04.09.06 20
Mo 07.08.2006 Mo 02.10.06 40

using System.Windows.Forms;
using System.Globalization;
using System;

namespace Arbeitstage
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void dateTimePicker2_ValueChanged(object sender,EventArgs e)
    {
      ArbeitstageNeuberechnen();
    }
    private void dateTimePicker1_ValueChanged(object sender,EventArgs e)
    {
      ArbeitstageNeuberechnen();
    }
    private void Form1_Load(object sender,EventArgs e)
    {
      ArbeitstageNeuberechnen();
    }
    private void ArbeitstageNeuberechnen()
    {
      txtArbeitstage.Text = DateInfo.Workdays(dateTimePicker1.Value,dateTimePicker2.Value).ToString();
    }

    class DateInfo
    {
      static int daysInWeek = DateTimeFormatInfo.CurrentInfo.DayNames.Length;
      static int workdaysInWeek = 0;
      static DateInfo()
      {
        for (int tag = 0; tag < daysInWeek; tag++)
          if (IsWorkDay(DateTime.Now.Date.AddDays(tag)))
            workdaysInWeek++;
      }

      /// <summary>Werktage *zwischen* d1 und d2</summary> 
      static public int Workdays(DateTime d1,DateTime d2)
      {
        d1 = d1.Date; d2 = d2.Date;
        if (d1 > d2) return Workdays(d2,d1);
        int Diff = DayDiff(d2,d1);
        if (Diff > daysInWeek) // auf eine Woche zurückführen: 
          return (Workdays(d1,d1.AddDays(
            (Diff % daysInWeek))) + (Diff / daysInWeek) * workdaysInWeek);
        int tage = 0; d2 = d2.AddDays(-1);
        for (DateTime dx = d1; DayDiff(d2,dx) >= 0; dx = dx.AddDays(1))
          if (IsWorkDay(dx)) tage++;
        return tage;
      }

      static private bool IsWorkDay(DateTime date)
      {
        return date.DayOfWeek != DayOfWeek.Saturday &&
            date.DayOfWeek != DayOfWeek.Sunday;
      }

      static private int DayDiff(DateTime d2,DateTime d1)
      {
        TimeSpan diff = (TimeSpan)(d2 - d1); return diff.Days;
      }
    }
  }
}