Auteur de questions
Calcul des fêtes mobiles pour une année ...

Discussion générale
-
CALCUL DES FETES MOBILES POUR UNE ANNEE
PÂQUES, L.PAQUES, ASCENSION, PENTECOTE, L.PENTECOTETous 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
Toutes les réponses
-
-
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âquesA = Year(d)
If A > 2099 Then
TypeJour = 0
Exit Function
End IfT = (((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 Module1Function 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
-
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
-
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 tienJ'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>
--
-
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
-
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