none
Calcul des fêtes mobiles pour une année ... RRS feed

  • Discussion générale

  • CALCUL DES FETES MOBILES POUR UNE ANNEE
    PÂQUES, L.PAQUES, ASCENSION, PENTECOTE, L.PENTECOTE

    Tous les calculs sont basés sur la date de Pâques, qui est la date anniversaire de la  résurrection de notre Christ.
    A partir de cette date de Pâques nous trouvons les 5 dates des fêtes religieues (jours fériés mobiles) ; soit : Pâques, Lundi de Pâques (Pâques + 1 jour), Ascension (Pâques + 39 jours "élévation de notre Christ"), Pentecôte (Pâques + 49 jours "descente de l'esprit Saint") et lundi de Pentecôte (Pâques + 50 jours).
    Nota bene : on compte 40 et 50 jours après Pâques pour respectivementl'Ascension et la Pentecôte, mais c'est parce qu'on compte les deux extrêmes.

    Pâques est célébré le dimanche qui suit le quatorzième jour de la lune (NL) qui atteint cet âge au 21 mars (équinoxe) ou immédiatement après (concile de Nicée "Turquie" en l'an 325).
    Les dates extrêmes incluses de Pâques vont du 22 mars au 25 avril lors de la PL. Toutefois la NL qui sert de base ("Lune" dixit le concile de Nicée) est la NL éclésiastique et non pas astronomique. En effet, à l'époque depuis le moyen-orient on ne savait pas exactement quand avait lieu la NL, puisqu'invisible de la terre, alors on attendait de voir le premier croissant pour déterminer la NL. Ceci crée une divergeance de quelques heures qui peuvent repousser jusqu'à 34 jours au maximum le calcul de Pâques ; d'autant que les calculs astronomiques se font pour l'équateur ou à l'équinoxe le jour et la nuit à la même durée.

    Exemples pour 2010 : le 1er jour de la NL juste avant l'équinoxe est le 15 mars, on va donc faire 15 mars + 14 jours = 29 mars, ici la NL a commencé avant l'équinoxe et 14 jours après nous avons dépassé ce dernier, donc les condition sont réunies, mais le 29 mars étant un lundi on va devoir avancer jusqu'au prochain dimanche qui sera Pâques le dimanche 4 Avril 2010.

    Le code du programme a été testé avec trois objets (form1, textBox1 et button1).
    Le Texte de l'année admis doit être entre 2049 et 34 inclus. Le calcul est dans le code du bouton, donc, bien penser à saisir l'année voulue en totalité, le résultat est dans un MessageBox.

    Option Explicit On
    Public Class Form1
     Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      TextBox1.Text = "Saisir l'année en entier"
     End Sub
    
     Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
      TextBox1.Focus()
     End Sub
    
     Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
      Select Asc(e.KeyChar)
       Case Is < 8 : e.KeyChar = vbNullChar
       Case 8
       Case 9 To 12 : e.KeyChar = vbNullChar
       Case 13
        Call Button1_Click(sender, e)
        Exit Sub
       Case 14 To 47 : e.KeyChar = vbNullChar
       Case Is > 57 : e.KeyChar = vbNullChar
      End Select
     End Sub
    
     Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      Dim an As Long = Val(TextBox1.Text)
      Dim jour As Long
      Dim mois As Long
      Dim A As Long
      Dim C As Long
      Dim D As Long
      Dim F As Long
      Dim G As Long
      Dim H As Long
      Dim I As Long
      Dim J As Long
      Dim K As Long
      Dim M As Long
      Dim N As Long
      Dim O As Long
      Dim P As Long
      Dim Q As Long
      Dim sngR As Double
      Dim chaine As String
      Dim paques As Date
      Dim lundiPaques As Date
      Dim ascension As Date
      Dim pentecote As Date
      Dim lundiPentecote As Date
      '
      If an < 34 Or an > 2049 Then
       MsgBox("L'année doit être comprise entre 2049 et 34, remédier ... ", vbExclamation)
       TextBox1.Focus()
       Exit Sub
      End If
      '
      A = an Mod 19
      c = Int(an / 100)
      D = 100 * ((an / 100) - Int(an / 100))
      F = Int(c / 4)
      G = 4 * (c / 4 - Int(c / 4))
      H = Int((8 + c) / 25)
      I = Int((1 + C - H) / 3)
      J = 15 + 19 * A + C - F - I
      K = Int(0.5 + 30 * (J / 30 - Int(J / 30)))
      M = Int(D / 4)
      N = 4 * (D / 4 - Int(D / 4))
      O = 32 + 2 * (G + m) - k - N
      P = Int(7 * (O / 7 - Int(O / 7)) + 0.5)
      Q = Int((a + 11 * k + 22 * p) / 451)
      sngR = (114 + k + p - 7 * Q) / 31
      mois = Int(sngR)
      jour = Int(31 * (sngR - Int(sngR)) + 1.5)
      '
      paques = DateSerial(an, mois, jour)
      lundiPaques = paques.AddDays(1)
      ascension = paques.AddDays(39)
      pentecote = paques.AddDays(49)
      lundiPentecote = paques.AddDays(50)
      '
      chaine = an & vbLf & vbLf
      chaine = chaine & "Dimanche " & paques & vbLf
      chaine = chaine & "Lundi  " & lundiPaques & vbLf
      chaine = chaine & "Jeudi  " & ascension & vbLf
      chaine = chaine & "Dimanche " & pentecote & vbLf
      chaine = chaine & "Lundi  " & lundiPentecote & vbLf
      MsgBox(chaine)
      TextBox1.Focus()
     End Sub ' button1_click
    End Class
    

    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    mardi 26 octobre 2010 21:50

Toutes les réponses

  • Merci Joe pour cet algo ça peut servir
    fred
    jeudi 28 octobre 2010 15:33
  • Bonjour fred,

    Très bonne réponse tu marques un point :o)

    Ça sert même souvent en programmation ...

    Cordialement.

     


    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 28 octobre 2010 17:03
  • Bonjour EhJoe

    Sans vouloir dénigrer ton travail (j'utilisais auparavant le même algo), j'en ai un autre plus compact

    en VBA/VB6 d'abord et VB.NET NON TESTÉ  mais cela devrait aller (la méthode .addDays est la seule différence)

    Cdt, Blaise

    ---------------  VBA/VB6
    Function TypeJour(d As Date)
    'Cette fonction renvoie 0 si le jour passé en paramètre est un jour de semaine,
    '1 s'il s'agit d'un samedi,  2 d'un dimanche et 3 s'il s'agit d'un jour férié.
    'Valide jusqu'en 2099 et pour les jours fériés belges
        Dim A As Integer, T As Integer
        Dim LP As Date 'Lundi de Pâques

        A = Year(d)

        If A > 2099 Then
            TypeJour = 0
            Exit Function
        End If

        T = (((255 - 11 * (A Mod 19)) - 21) Mod 30) + 21
        LP = DateSerial(A, 3, 2) + T + (T > 48) + 6 - ((A + A \ 4 + T + (T > 48) + 1) Mod 7)

        Select Case d
            Case LP, LP + 38, LP + 49       ' Jours fériés mobiles
                TypeJour = 3
                ' Jours fériés fixes belges
            Case DateSerial(A, 1, 1), _
                    DateSerial(A, 5, 1), _
                    DateSerial(A, 5, 8), _
                    DateSerial(A, 7, 21), _
                    DateSerial(A, 11, 1), _
                    DateSerial(A, 11, 11), _
                    DateSerial(A, 12, 25)
                TypeJour = 3
            Case Else
                ' Samedi ou dimanche
                If Weekday(d, vbMonday) = 6 Then
                    TypeJour = 1
                End If
                If Weekday(d, vbMonday) = 7 Then
                    TypeJour = 2
                End If
        End Select
    End Function

    ------------------------VB.NET
    Module Module1

    Function TypeJour(ByVal d As Date)

    'Cette fonction renvoie 0 si le jour pass en paramtre est un jour de semaine,

    '1 s'il s'agit d'un samedi, 2 d'un dimanche et 3 s'il s'agit d'un jour fri.

    'Valide jusqu'en 2099 et pour les jours fris belges

    Dim A As Integer, T As Integer

    Dim Lp As Date 'Lundi de Pques

    A = Year(d)

    TypeJour = 0

    If A > 2099 Then

    Exit Function

    End If

    T = (((255 - 11 * (A Mod 19)) - 21) Mod 30) + 21

    Lp = DateSerial(A, 3, 2)

    Lp = Lp.AddDays(T + (T > 48) + 6 - ((A + A \ 4 + T + (T > 48) + 1) Mod 7))

    Select Case d

    Case Lp, Lp.AddDays(38), Lp.AddDays(49) ' Jours fris mobiles

    TypeJour = 3

    ' Jours fris fixes belges

    Case DateSerial(A, 1, 1), _

    DateSerial(A, 5, 1), _

    DateSerial(A, 5, 8), _

    DateSerial(A, 7, 21), _

    DateSerial(A, 11, 1), _

    DateSerial(A, 11, 11), _

    DateSerial(A, 12, 25)

    TypeJour = 3

    Case Else

    ' Samedi ou dimanche

    If Weekday(d, vbMonday) = 6 Then

    TypeJour = 1

    ElseIf Weekday(d, vbMonday) = 7 Then

    TypeJour = 2

    End If

    End Select

    End Function

    End Module

    vendredi 29 octobre 2010 14:57
  • Bonjour Blaise,

    Ta fonction vbNet n'est pas bonne, tu demandes un date, or pour trouver les jours fériés mobiles d'une année ce n'est pas une date qu'il faut passer, il faut passer l'année évidemment, donc un long, et en retour une date si tu veux ...

    Mon programme ne demande pas si un jour est férié, ce serait contre-productif, il faudrait demander à chaque journ, non, on entre l'année, et pour l'année il donne les 5 fériés ..

    Cordialement.

     


    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    • Modifié EhJoe samedi 30 octobre 2010 06:38 addebdum 2
    vendredi 29 octobre 2010 18:08
  • Bonjour EhJoe

    Tu n'as pas bien compris l'esprit de ma participation.

    Ma fonction n'a rien à voir avec l'objectif de ton programme (qui est d'afficher les jours fériés mobiles pour une année).
    Je voulais simplement faire comparer les deux algos, celui que j'utilise étant plus compact : 3 lignes et 3 variables pour obtenir le lundi de Pâques contre 18 lignes et quasiment autant de variables pour le tien

    J'ai vu  en EXCEL une formule encore plus audacieuse pour Pâques: =FRANC(("4/"&A1)/7+MOD(19*MOD(A1;19)-7;30)*14%;)*7-6 (l'année étant en A1 et entre 1901 et 2099).

    Ma fonction cherche simplement le type de jour, pour prévenir qu'on ne travaille pas les dimanches et jours fériés dans l'entreprise.  Je m'en sers aussi pour calculer le nombre de jours ouvrables entre deux dates.
    Quand je passe une date, je passe aussi une année 'A = Year(d)'

    Comme j'ai réinstallé VB2008, j'ai eu l'occasion de la tester et elle fonctionne fort bien.  Je conseille seulement de modifier une ligne : Select Case d.Date  (d.DATE pour une date sans l'heure)

    Dans le message suivant, TON programme avec l'algo que j'utilise.

    Très cordialement et bien à toi,

    Blaise

    <EhJoe> a écrit dans le message de news: 7f1dde27-cad3-491e-8736-513a96065ed3@communitybridge.codeplex.com...

    Bonjour Blaise,

    Ta fonction vbNet n'est pas bonne, tu demandes un date, or pour trouver les jours fériés mobiles d'une année ce n'est pas une date qu'il faut passer, il faut passer l'année évidemment, donc un long, et en retour une date si tu veux ...

    Mon programme ne demande pas si un jour est férié, ce serait contre-productif, il faudrait demander à chaque journ, non, on entre l'année, et pour l'année il donne les 5 fériés ..

    Cordialement.


    Joseph Attila PUSZTAY
    EhJoe  <http://irolog.free.fr/joe/index.htm> Logiciels <http://irolog.free.fr> Romans <http://irolog.free.fr/_gratuit/10romansGratuits/index.htm> Ecrire <mailto:montmartre75018@free.fr>

    --

    samedi 30 octobre 2010 14:47
  • Salut EhJoe,

    Comme promis, le code via l'interface WEB (un peu plus lisible ;-)

    Je te souhaite un bon long W.E.,

    Blaise

    Public Class Form1
    
      Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        Select Case Asc(e.KeyChar)
          Case Is < 8, 9 To 12, 14 To 47, Is > 57
            e.KeyChar = vbNullChar
          Case 13
            Call Button1_Click(sender, e)
            Exit Sub
          Case Else
            ' rien
        End Select
      End Sub
    
    
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim A As Integer = Val(TextBox1.Text) 'Année
        Dim T As Long
        Dim Lp As Date 'Lundi de Pques
        Dim sS As String
        If A < 1901 Or A > 2099 Then
          MsgBox("L'année doit être comprise entre 2099 (et 1901 ?), remédier ... ", vbExclamation)
          TextBox1.Focus()
          Exit Sub
        End If
        T = (((255 - 11 * (A Mod 19)) - 21) Mod 30) + 21
        Lp = DateSerial(A, 3, 2)
        Lp = Lp.AddDays(T + (T > 48) + 6 - ((A + A \ 4 + T + (T > 48) + 1) Mod 7))
        sS = "Année " & A & vbCrLf & vbCrLf _
          & "Pâques le dimanche " & Lp.AddDays(-1) & vbCrLf _
          & "Lundi de Pâques le " & Lp & vbCrLf _
          & "Ascension le jeudi " & Lp.AddDays(38) & vbCrLf _
          & "Pentecôte le dimanche " & Lp.AddDays(48) & vbCrLf _
          & "Lundi de Pentecôte le " & Lp.AddDays(49) & vbCrLf & vbCrLf _
          & "Amen !"
    
        MsgBox(sS)
        TextBox1.Focus()
      End Sub ' button1_click
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        TextBox1.Text = Year(Date.Today)
      End Sub
    
    End Class
    
    
    samedi 30 octobre 2010 15:21
  • Bonjour Blaise,

    Ça donne ça :

     Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Dim A As Long = CLng(TextBox1.Text) 'Année
     Dim T As Long
     Dim Lp As Date 'Lundi de Pques
     Dim sS As String
     A = Val(TextBox1.Text)
     T = (((255 - 11 * (A Mod 19)) - 21) Mod 30) + 21
     Lp = DateSerial(A, 3, 2)
     Lp = Lp.AddDays(T + (T > 48) + 6 - ((A + A \ 4 + T + (T > 48) + 1) Mod 7))
     sS = "Année " & A & vbCrLf & vbCrLf
     sS = sS & "Pâques le dimanche " & Lp.AddDays(-1) & vbLf
     sS = sS & "Lundi de Pâques le " & Lp & vbLf
     sS = sS & "Ascension le jeudi " & Lp.AddDays(38) & vbLf
     sS = sS & "Pentecôte le dimanche " & Lp.AddDays(48) & vbLf
     sS = sS & "Lundi de Pentecôte le " & Lp.AddDays(49)
     MsgBox(sS)
     TextBox1.Focus()
     End Sub
    

    C'est normal les variables prennent de multiples calculs, alors que moi je décortique bien, ne serait que pour tester c'est plus cclair.

    Par contre le calcul est faut avant 1901, et ça doit aller en "34".

    Merci, bon wee-end, cordialement.

     


    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire

    • Modifié EhJoe samedi 30 octobre 2010 15:41 Addendum
    samedi 30 octobre 2010 15:38