Feiertags DLL erstellen

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von us4711.

    Feiertags DLL erstellen

    hallo leute

    als erstes mal vorweg: zum erstellen von dll's habe ich mir dieses tutorial angesehen:
    Tutorial

    Nun habe ich eine Möglichkeit gefunden alle gewünschten Feiertage zu berechnen:
    Feiertage berechnen

    Hier ist es relativ übersichtlich und klar dargestellt die ganze berechnung der einzelnen tage.
    nun möchte ich es aber so machen, dass alle berechnungsschritte in der dll stattfinden und nur der letzte abschnitt des 2. links ("Alle Feiertage in der ListBox anzeigen") in der eigentlichen Form im code benötigt wird.

    nun bekomme ich errors und warnungen. unter anderem kann ich in der class liabry den Typ "TypeFeiertag" nicht definieren.
    und dass in die Return-Anweisung in den einzelnen Funktionen fehlt.

    Könnt ihr mir hierbei weiterhelfen wie ich das machen muss? habe null ahnung davon leider :(

    danke
    @FrozzenApple:: Hast Du einen Code, der ohne DLL funktioniert?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    FrozzenApple schrieb:

    könnt ihr mir bei der anpassung helfen?
    Poste mal Deinen Code.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    FrozzenApple schrieb:

    es ist der aus dem 2. link
    Wir sollen Dir aus fremdem Code Deine DLL machen? :thumbdown:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    FrozzenApple schrieb:

    wo genau man ansetzen muss
    Dazu solltest Du uns mal zeigen, was Du bereits gemacht hast.
    Wozu soll ich für Dich fremden Code verstehen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @FrozzenApple:: Hättest Du jetzt so was geschrieben wie:
    Die Deppen von dem Link haben den 1. Mai als "Maifeiertag" und als "Tag der Arbeit" verkauft oder so, hätten wir gemerkt, dass Du zumindest mal reingesehen hast.
    Also.
    Das ist grottiger VB6-Code, den solltest Du zunächst im mühevoller Kleinarbeit nach VB.NET überführen.
    Wenn Du das getan hast, wirst Du auch schon etwas Erfahrung mit diesem Code gesammelt haben, dann stell weitere Fragen. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    In der Tat ist vieles, was im Netz rumgeistert, noch auf VB6 ausgelegt und funktioniert so in .NET entweder gar nicht (siehe "Private Type") oder ist viel zu umständlich.

    Ich wette, selbst die leidlich kopierte "Gauß-Berechnung" des Ostersonntags, müsste in .NET um ein Vielfaches eleganter lösbar sein als das von Microsoft im verlinkten MSDN-Artikel angegeben ist, denn der Code dort sieht im Grunde genauso aus, was vor 10 Jahren schon für VB6 gebastelt wurde und nimmt keinerlei Rücksicht darauf, dass es mit der aktuellen DateTime-Klasse vllt besser lösbar ist.

    Das hier wäre meine Lösung als Extension, wobei ich tatsächlich nur Feiertage berücksichtigt habe, (Silvester, Rosenmontag und Co. sind keine Feiertage!) und auch nur die deutschen, davon allerdings alle, unabhängig vom Bundesland (Buß- und Bettag z.B. gibts nur noch IMHO in Sachsen).

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.CompilerServices
    2. Namespace System
    3. <Extension()>
    4. Module exDateTime
    5. Public Enum Feiertage
    6. None = 0
    7. Neujahr
    8. HeiligeDreiKoenige
    9. Maifeiertag
    10. TagDerDeutschenEinheit
    11. ErsterWeihnachtsfeiertag
    12. ZweiterWeihnachtsfeiertag
    13. Reformationstag
    14. Allerheiligen
    15. MariaHimmelfahrt
    16. Karfreitag
    17. Ostersonntag
    18. Ostermontag
    19. Pfingstsonntag
    20. Pfingstmontag
    21. ChristiHimmelfahrt
    22. Fronleichnam
    23. BussUndBettag
    24. End Enum
    25. <Extension()>
    26. Public Function GetFeiertag(ByVal datum As DateTime) As Feiertage
    27. With datum
    28. If .Day = 1 And .Month = 1 Then
    29. Return Feiertage.Neujahr
    30. ElseIf .Day = 6 And .Month = 1 Then
    31. Return Feiertage.HeiligeDreiKoenige
    32. ElseIf .Day = 1 And .Month = 5 Then
    33. Return Feiertage.Maifeiertag
    34. ElseIf .Day = 3 And .Month = 10 Then
    35. Return Feiertage.TagDerDeutschenEinheit
    36. ElseIf .Day = 25 And .Month = 12 Then
    37. Return Feiertage.ErsterWeihnachtsfeiertag
    38. ElseIf .Day = 26 And .Month = 12 Then
    39. Return Feiertage.ZweiterWeihnachtsfeiertag
    40. ElseIf .Day = 31 And .Month = 10 Then
    41. Return Feiertage.Reformationstag
    42. ElseIf .Day = 1 And .Month = 11 Then
    43. Return Feiertage.Allerheiligen
    44. ElseIf .Day = 15 AndAlso .Month = 8 Then
    45. Return Feiertage.MariaHimmelfahrt
    46. End If
    47. Dim ostern As DateTime = GetOstersonntag(.Year)
    48. If .Day = ostern.Day And .Month = ostern.Month Then
    49. Return Feiertage.Ostersonntag
    50. End If
    51. Dim ostermontag As DateTime = ostern.AddDays(1)
    52. If .Day = ostermontag.Day And .Month = ostermontag.Month Then
    53. Return Feiertage.Ostermontag
    54. End If
    55. Dim karfreitag As DateTime = ostern.AddDays(-2)
    56. If .Day = karfreitag.Day And .Month = karfreitag.Month Then
    57. Return Feiertage.Karfreitag
    58. End If
    59. Dim pfingsten = ostern.AddDays(49)
    60. If .Day = pfingsten.Day And .Month = pfingsten.Month Then
    61. Return Feiertage.Pfingstsonntag
    62. End If
    63. Dim pfingstmontag = pfingsten.AddDays(1)
    64. If .Day = pfingstmontag.Day And .Month = pfingstmontag.Month Then
    65. Return Feiertage.Pfingstmontag
    66. End If
    67. Dim christiHF = ostern.AddDays(39)
    68. If .Day = christiHF.Day And .Month = christiHF.Month Then
    69. Return Feiertage.ChristiHimmelfahrt
    70. End If
    71. Dim fronleichnam = ostern.AddDays(60)
    72. If .Day = fronleichnam.Day AndAlso .Month = fronleichnam.Month Then
    73. Return Feiertage.Fronleichnam
    74. End If
    75. Dim bussundbettag = New DateTime(.Year, 11, 26)
    76. bussundbettag = bussundbettag.AddDays(-(4 + bussundbettag.DayOfWeek))
    77. If .Day = bussundbettag.Day AndAlso .Month = bussundbettag.Month Then
    78. Return Feiertage.BussUndBettag
    79. End If
    80. End With
    81. Return Feiertage.None
    82. End Function
    83. Public Function GetOstersonntag(ByVal year As Integer) As DateTime
    84. Dim a As Integer = year Mod 19
    85. Dim b As Integer = year \ 100
    86. Dim c As Integer = (8 * b + 13) \ 25 - 2
    87. Dim d As Integer = b - (year \ 400) - 2
    88. Dim e As Integer = (19 * (year Mod 19) + ((15 - c + d) Mod 30)) Mod 30
    89. If e = 28 Then
    90. If a > 10 Then
    91. e = 27
    92. End If
    93. ElseIf e = 29 Then
    94. e = 28
    95. End If
    96. Dim f As Integer = (d + 6 * e + 2 * (year Mod 4) + 4 * (year Mod 7) + 6) Mod 7
    97. Return New DateTime(year, 3, 22).AddDays(e + f)
    98. End Function
    99. End Module
    100. End Namespace
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    sehr hübsch! :thumbsup:

    guck - ich habs noch mehr gehübscht:

    VB.NET-Quellcode

    1. Public Enum Feiertage
    2. None = 0
    3. Neujahr = 1 + 1 << 16
    4. HeiligeDreiKoenige = 6 + 1 << 16
    5. Maifeiertag = 1 + 5 << 16
    6. MariaHimmelfahrt = 15 + 8 << 16
    7. TagDerDeutschenEinheit = 3 + 10 << 16
    8. Reformationstag = 31 + 10 << 16
    9. Allerheiligen = 1 + 11 << 16
    10. ErsterWeihnachtsfeiertag = 25 + 12 << 16
    11. ZweiterWeihnachtsfeiertag = 26 + 12 << 16
    12. Karfreitag = 2
    13. Ostersonntag
    14. Ostermontag
    15. ChristiHimmelfahrt
    16. Pfingstsonntag
    17. Pfingstmontag
    18. Fronleichnam
    19. BussUndBettag
    20. End Enum
    21. <Extension()>
    22. Public Function GetFeiertag(ByVal datum As DateTime) As Feiertage
    23. Dim n = datum.Day + datum.Month << 16
    24. If [Enum].IsDefined(GetType(Feiertage), n) Then Return DirectCast(n, Feiertage)
    25. datum = datum.Date
    26. Dim ostern As DateTime = GetOstersonntag(datum.Year)
    27. If datum = ostern Then Return Feiertage.Ostersonntag
    28. If datum = ostern.AddDays(-2) Then Return Feiertage.Karfreitag
    29. If datum = ostern.AddDays(1) Then Return Feiertage.Ostermontag
    30. If datum = ostern.AddDays(39) Then Return Feiertage.ChristiHimmelfahrt
    31. If datum = ostern.AddDays(49) Then Return Feiertage.Pfingstsonntag
    32. If datum = ostern.AddDays(50) Then Return Feiertage.Pfingstmontag
    33. If datum = ostern.AddDays(60) Then Return Feiertage.Fronleichnam
    34. With New DateTime(datum.Year, 11, 26)
    35. If datum = .AddDays(-(4 + .DayOfWeek)) Then Return Feiertage.BussUndBettag
    36. End With
    37. Return Feiertage.None
    38. End Function


    Edit: aufgrund Arbys Einwand zeile#26 eingefügt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    guck - ich habs noch mehr gehübscht:

    Sieht auf den ersten Blick sehr schön aus. Hat aber einen kleinen Schönheitsfehler. Wenn man es mit einem DateTime-Objekt aufruft, das zusätzlich auch eine Zeit definiert hat, dürfte der Feiertag nicht mehr korrekt erkannt werden, wenn es sich um einen beweglichen handelt (darum hab ich soviel mit .Day=x.Day AndAlso .Month=x.Month rumgewurschtelt).
    Ich habs nicht getestet, aber wenn es wider Erwarten doch funktionieren sollte, hat Microsoft eine seltsame Vorstellung davon, was beim Vergleich von DateTime-Objekten mit unterschiedlichen Zeiten passieren soll.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Für die rheinischen Frohnaturen unter uns fehlen in der Enum 3 wichtige Daten (Zeilen 13, 14 und 15)

    VB.NET-Quellcode

    1. Public Enum Feiertage
    2. None = 0
    3. Neujahr = 1 + 1 << 16
    4. HeiligeDreiKoenige = 6 + 1 << 16
    5. Maifeiertag = 1 + 5 << 16
    6. MariaHimmelfahrt = 15 + 8 << 16
    7. TagDerDeutschenEinheit = 3 + 10 << 16
    8. Reformationstag = 31 + 10 << 16
    9. Allerheiligen = 1 + 11 << 16
    10. ErsterWeihnachtsfeiertag = 25 + 12 << 16
    11. ZweiterWeihnachtsfeiertag = 26 + 12 << 16
    12. Karfreitag = 2
    13. Weiberfastnacht
    14. Rosenmontag
    15. Aschermittwoch
    16. Ostersonntag
    17. Ostermontag
    18. ChristiHimmelfahrt
    19. Pfingstsonntag
    20. Pfingstmontag
    21. Fronleichnam
    22. BussUndBettag
    23. End Enum


    Dann muss allerdings auch die Extension abgeändert werden, da sonst immer TagDerDeutschenEinheit zurückgegeben wird Zeilen 18 und 19 nach unten verschoben):

    VB.NET-Quellcode

    1. <Extension()>
    2. Public Function GetFeiertag(ByVal datum As DateTime) As Feiertage
    3. datum = datum.Date
    4. Dim ostern As DateTime = GetOstersonntag(datum.Year)
    5. If datum = ostern Then Return Feiertage.Ostersonntag
    6. If datum = ostern.AddDays(-45) Then Return Feiertage.Weiberfastnacht
    7. If datum = ostern.AddDays(-41) Then Return Feiertage.Rosenmontag
    8. If datum = ostern.AddDays(-39) Then Return Feiertage.Aschermittwoch
    9. If datum = ostern.AddDays(-2) Then Return Feiertage.Karfreitag
    10. If datum = ostern.AddDays(1) Then Return Feiertage.Ostermontag
    11. If datum = ostern.AddDays(39) Then Return Feiertage.ChristiHimmelfahrt
    12. If datum = ostern.AddDays(49) Then Return Feiertage.Pfingstsonntag
    13. If datum = ostern.AddDays(50) Then Return Feiertage.Pfingstmontag
    14. If datum = ostern.AddDays(60) Then Return Feiertage.Fronleichnam
    15. With New DateTime(datum.Year, 11, 26)
    16. If datum = .AddDays(-(4 + .DayOfWeek)) Then Return Feiertage.BussUndBettag
    17. End With
    18. Dim n = datum.Day + datum.Month << 16
    19. If [Enum].IsDefined(GetType(Feiertage), n) Then Return DirectCast(n, Feiertage)
    20. Return Feiertage.None
    21. End Function

    us4711 schrieb:

    Für die rheinischen Frohnaturen unter uns fehlen in der Enum 3 wichtige Daten ...

    Sorry, aber das ist Unsinn. Wie ich schrieb: Das sind keine gesetzlichen Feiertage. Und um die ging's.
    Hab ich schonmal erwähnt, dass ich mit Fasching, Fastnacht, Karneval so gar nix anfangen kann?

    us4711 schrieb:

    Dann muss allerdings auch die Extension abgeändert werden, da sonst immer TagDerDeutschenEinheit zurückgegeben wird Zeilen 18 und 19 nach unten verschoben):

    Auch das halte ich für Unsinn. @ErfinderDesRades: hat das Enum bereits so konzeptioniert, dass genau das eben nicht passieren sollte. Oder was glaubst du haben die vielen "<<" im Code zu suchen? Im großen und ganzen ist der Code nämlich ohne diese Umstellung etwas performanter.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.

    Arby schrieb:

    Hab ich schonmal erwähnt, dass ich mit Fasching, Fastnacht, Karneval so gar nix anfangen kann?

    Friedrich der Große: "Jeder soll nach seiner Fasson selig werden."

    Arby schrieb:

    Auch das halte ich für Unsinn. @ErfinderDesRades: hat das Enum bereits so konzeptioniert ...

    Große Worte ... hast Du's denn mal ausprobiert? Oder noch mehr, hast Du den Code von @ErfinderDesRades denn überhaupt verstanden?
    Wenn Ja, dann erklär' mir doch, was denn da eigentlich geschieht ...
    Hupsala!
    Habe einen Irrtum mit den Operator-Vorrängen: + ist vorrangig vor << - daher die Fehl-Ergebnisse.
    Korrektur: Klammern setzen.

    Dann hab hab ich deine "Feiertage" integriert, und funktionierte problemlos ohne Umstellung. Kommt keinesfalls der Tag der dt Einheit.

    VB.NET-Quellcode

    1. Public Enum Feiertage
    2. None = 0
    3. Neujahr = 1 + (1 << 16)
    4. HeiligeDreiKoenige = 6 + (1 << 16)
    5. Maifeiertag = 1 + (5 << 16)
    6. MariaHimmelfahrt = 15 + (8 << 16)
    7. TagDerDeutschenEinheit = 3 + (10 << 16)
    8. Reformationstag = 31 + (10 << 16)
    9. Allerheiligen = 1 + (11 << 16)
    10. ErsterWeihnachtsfeiertag = 25 + (12 << 16)
    11. ZweiterWeihnachtsfeiertag = 26 + (12 << 16)
    12. Karfreitag = 2
    13. Weiberfastnacht
    14. Rosenmontag
    15. Aschermittwoch
    16. Ostersonntag
    17. Ostermontag
    18. ChristiHimmelfahrt
    19. Pfingstsonntag
    20. Pfingstmontag
    21. Fronleichnam
    22. BussUndBettag
    23. End Enum
    24. Private _HolyDays As New HashSet(Of Integer)(DirectCast([Enum].GetValues(GetType(Feiertage)), Integer()))
    25. <Extension()>
    26. Public Function GetFeiertag(ByVal datum As DateTime) As Feiertage
    27. datum = datum.Date
    28. Dim n = datum.Day + (datum.Month << 16)
    29. If _HolyDays.Contains(n) Then Return DirectCast(n, Feiertage)
    30. Dim ostern As DateTime = GetOstersonntag(datum.Year)
    31. If datum = ostern.AddDays(-45) Then Return Feiertage.Weiberfastnacht
    32. If datum = ostern.AddDays(-41) Then Return Feiertage.Rosenmontag
    33. If datum = ostern.AddDays(-39) Then Return Feiertage.Aschermittwoch
    34. If datum = ostern.AddDays(-2) Then Return Feiertage.Karfreitag
    35. If datum = ostern Then Return Feiertage.Ostersonntag
    36. If datum = ostern.AddDays(1) Then Return Feiertage.Ostermontag
    37. If datum = ostern.AddDays(39) Then Return Feiertage.ChristiHimmelfahrt
    38. If datum = ostern.AddDays(49) Then Return Feiertage.Pfingstsonntag
    39. If datum = ostern.AddDays(50) Then Return Feiertage.Pfingstmontag
    40. If datum = ostern.AddDays(60) Then Return Feiertage.Fronleichnam
    41. With New DateTime(datum.Year, 11, 26)
    42. If datum = .AddDays(-(4 + .DayOfWeek)) Then Return Feiertage.BussUndBettag
    43. End With
    44. Return Feiertage.None
    45. End Function
    Test:

    VB.NET-Quellcode

    1. Dim dt = New Date(1999, 5, 1)
    2. Dim h = dt.GetFeiertag
    3. h = #4/20/2014#.GetFeiertag
    4. h = #4/20/2014#.AddDays(-39).GetFeiertag
    5. h = Date.Today.GetFeiertag
    6. h = #4/20/2014#.GetFeiertag
    Aber ich teste nochmal das Enum.IsDefined - nicht dasses da doch noch sone Üraschung gibt.

    Edit: Jo: Enum.IsDefined verhält sich auch anners, als ich dachte - hab ich jetzt also mit einem HashSet gelöst, was ich selbst nicht so dolle finde :(

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()