I wrote a simple dll which is able to calculate all common holidays, but, I would like to optimize the code in readability and flexibility.
Federal state
public enum Bundesland
{
BadenWürttemberg,
Bayern,
Berlin,
Brandenburg,
Bremen,
Hamburg,
Hessen,
MecklenburgVorpommern,
Niedersachsen,
NordrheinWestfalen,
RheinlandPfalz,
Saarland,
Sachsen,
SachsenAnhalt,
SchleswigHolstein,
Thüringen
}
holiday
/// <summary>
/// Representiert den Feiertag mit
/// allen wichtigen informationen
/// </summary>
public class Feiertag : IComparable<Feiertag>
{
private bool isFix;
private DateTime datum;
private string name;
public Feiertag(bool isFix, DateTime datum, string name)
{
this.IsFix = isFix;
this.Datum = datum;
this.Name = name;
}
/// <summary>
/// Der Name des Feiertages
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
/// <summary>
/// Das Datum an dem dieser Feiertag stattfindet
/// </summary>
public DateTime Datum
{
get { return datum; }
set { datum = value; }
}
/// <summary>
/// Zeigt an ob es sich um einen Datums spezifischer
/// oder zyklisch Feiertag handelt
/// </summary>
public bool IsFix
{
get { return isFix; }
set { isFix = value; }
}
#region IComparable<Feiertag> Member
public int CompareTo(Feiertag other)
{
return this.datum.Date.CompareTo(other.datum.Date);
}
#endregion IComparable<Feiertag> Member
}
holidaylogic
:
/// <summary>
/// Hält eine Liste von Feiertagen für die Jahr Monat Kombination
/// </summary>
public class MyFeiertagLogic
{
private static MyFeiertagLogic Instance;
private List<Feiertag> feiertage;
private int year;
/// <summary>
/// Das Jahr für welches die Feiertage berechnet werden
/// </summary>
public int CurrentYear
{
get { return year; }
set { year = value; }
}
/// <summary>
/// Erzeugt eine neue Instanz der Feiertage für das Übergebene Jahr außerdem wird davon ausgegangen das es sich bei dem Bundesland um Sachsen handelt
/// </summary>
/// <param name="year">Das Jahr für welches Die Feiertaglogic Initialisiert werden soll</param>
/// <returns></returns>
public static MyFeiertagLogic GetInstance(int year)
{
if (Instance == null || year != Instance.CurrentYear)
{
Instance = new MyFeiertagLogic(year, Bundesland.Sachsen);
return Instance;
}
return Instance;
}
/// <summary>
/// Erzeugt eine neue Instanz der Feiertage für das Übergebene Jahr und Bundesland
/// </summary>
/// <param name="year">Das Jahr für welches Die Feiertaglogic Initialisiert werden soll</param>
/// <param name="bl">Das Bundesland welches zur Ermittlung der Feiertage betrachtet werden soll</param>
/// <returns></returns>
public static MyFeiertagLogic GetInstance(int year, Bundesland bl)
{
if (Instance == null || year != Instance.CurrentYear)
{
Instance = new MyFeiertagLogic(year, bl);
return Instance;
}
return Instance;
}
/// <summary>
/// Beschreibung: Gibt variable Feiertage zurueck
/// </summary>
public List<Feiertag> Feiertagliste
{
get { return feiertage; }
}
/// <summary>
/// prüft ob das übermittelte Datum ein Feiertag ist
/// </summary>
/// <param name="value">zu prüfendes Datum</param>
/// <returns>True wenn ja</returns>
public bool isFeiertag(DateTime value)
{
return (feiertage.Find(delegate(Feiertag f) { return f.Datum.Date == value.Date; }) != null);
}
/// <summary>
/// gibt den Names des Feirtages zurück wenn das
/// übergebene Datum ein Feiertag ist
/// </summary>
/// <param name="value">Feiertagsdatum</param>
/// <returns>Name des Feiertages</returns>
public Feiertag GetFeiertagName(DateTime value)
{
return (feiertage.Find(delegate(Feiertag f) { return f.Datum.Date == value.Date; }));
}
/// <summary>
/// Beschreibung: gibt feste Feiertage zurueck
/// </summary>
public List<Feiertag> FesteFeiertage
{
get { return feiertage.FindAll(delegate(Feiertag f) { return f.IsFix; }); }
}
private MyFeiertagLogic(int year, Bundesland BL)
{
this.CurrentYear = year;
#region fillList
DateTime osterSonntag = GetOsterSonntag();
DateTime bußuBettag = GetBußuBetTag();
this.feiertage = new List<Feiertag>();
//alle Bundesländer
this.feiertage.Add(new Feiertag(true, new DateTime(year, 1, 1), "Neujahr"));
if (BL == Bundesland.BadenWürttemberg || BL == Bundesland.Bayern || BL == Bundesland.SachsenAnhalt)
this.feiertage.Add(new Feiertag(true, new DateTime(year, 1, 6), "Heilige Drei Könige"));
//if(BL == Bundesland.BadenWürttemberg)
//this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(-3), "Gründonnerstag"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(-2), "Karfreitag"));
if (BL == Bundesland.Brandenburg)
this.feiertage.Add(new Feiertag(false, osterSonntag, "Ostersonntag"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(1), "Ostermontag"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(true, new DateTime(year, 5, 1), "Tag der Arbeit"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(39), "Christi Himmelfahrt"));
if (BL == Bundesland.Brandenburg)
this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(49), "Pfingstsonntag"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(50), "Pfingstmontag"));
if (BL == Bundesland.BadenWürttemberg || BL == Bundesland.Bayern || BL == Bundesland.Hessen || BL == Bundesland.NordrheinWestfalen || BL == Bundesland.RheinlandPfalz || BL == Bundesland.Saarland)
this.feiertage.Add(new Feiertag(false, osterSonntag.AddDays(60), "Fronleichnam"));
if (/*BL == Bundesland.Bayern || */ BL == Bundesland.Saarland)
this.feiertage.Add(new Feiertag(true, new DateTime(year, 8, 15), "Mariä Himmelfahrt"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(true, new DateTime(year, 10, 3), "Tag der dt. Einheit"));
if (BL == Bundesland.Brandenburg || BL == Bundesland.MecklenburgVorpommern || BL == Bundesland.Sachsen || BL == Bundesland.SachsenAnhalt || BL == Bundesland.Thüringen)
this.feiertage.Add(new Feiertag(true, new DateTime(year, 10, 31), "Reformationstag"));
if (BL == Bundesland.BadenWürttemberg || BL == Bundesland.Bayern || BL == Bundesland.NordrheinWestfalen || BL == Bundesland.RheinlandPfalz || BL == Bundesland.Saarland)
this.feiertage.Add(new Feiertag(true, new DateTime(year, 11, 1), "Allerheiligen "));
if (BL == Bundesland.Sachsen)
this.feiertage.Add(new Feiertag(false, bußuBettag, "Buß- u. Bettag"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(true, new DateTime(year, 12, 25), "1. Weihnachtstag"));
//alle Bundesländer
this.feiertage.Add(new Feiertag(true, new DateTime(year, 12, 26), "2. Weihnachtstag"));
#endregion fillList
}
/// <summary>
/// Berechnet für das CurrentYear den Ostersonntag
/// </summary>
/// <returns>Datum für Ostersonntag</returns>
private DateTime GetOsterSonntag()
{
int g, h, c, j, l, i;
g = this.year % 19;
c = this.year / 100;
h = ((c - (c / 4)) - (((8 * c) + 13) / 25) + (19 * g) + 15) % 30;
i = h - (h / 28) * (1 - (29 / (h + 1)) * ((21 - g) / 11));
j = (this.year + (this.year / 4) + i + 2 - c + (c / 4)) % 7;
l = i - j;
int month = (int)(3 + ((l + 40) / 44));
int day = (int)(l + 28 - 31 * (month / 4));
return new DateTime(this.year, month, day);
}
/// <summary>
/// Berechnet für das CurrentYear den Buß- und Bettag
/// </summary>
/// <returns>Datum für Buß- und Bettag</returns>
public DateTime GetBußuBetTag()
{
/// Buß- und Bettag ist immer der
/// Mittwoch vor dem 23. November
var nov = new DateTime(this.year, 11, 23);
for (int i = -1; i < 10; i--)
{
var d = nov.AddDays(i);
if (d.DayOfWeek == DayOfWeek.Wednesday)
return d;
}
throw new IndexOutOfRangeException("BußuBetTag konnte nicht gefunden werden");
}
}
Usage:
var feiertage = MyFeiertagLogic.GetInstance(date.Year);
var isfeiertag = feiertage.isFeiertag(date);