Code : Tout sélectionner
#Include <Array.au3>
#include <Date.au3>
Global Const $never = "9999/12/31" ; date de "fin du monde" = jamais
Global $_dates_fetes ; la table des dates de fêtes pour l'année traitée
Global $_annee_fetes ; année pour laquelle les dates de fêtes mobiles sont actuellement calculées
; Renvoie le nombre de jours ouvrés entre deux dates exprimées sous forme AAAA/MM/JJ
;
; Ce calcul tient compte des dimanches et jours fériés (y compris les fêtes mobiles) et
; des variations "politiques", par exemple la gestion à géométrie variable du lundi de
; Pentecôte en France.
Func _NbJoursOuvres($dtDebut, $dtFin)
Local $d1, $dow, $date, $delta
If $dtDebut = $dtFin Then
Return(0)
EndIf
If $dtDebut > $dtFin Then
$date = $dtFin
$dtFin = $dtDebut
Else
$date = $dtDebut
EndIf
$d1 = StringSplit($date, '/-')
$dow = _DateToDayOfWeekISO($d1[1], $d1[2], $d1[3]) - 1
$delta = 0
While $date < $dtFin
$date = _DateAdd('D', 1, $date) ; date + 1
$dow += 1 ; jour de la semaine + 1
$d1 = StringLeft($date, 4) ; on vérifie s'il y a changement d'année
If $_annee_fetes <> $d1 Then ; si oui, on calcule les fêtes mobiles de la nouvelle année
$_annee_fetes = $d1
_DateFetesMobiles($_annee_fetes)
EndIf
If Mod($dow, 7) <> 6 And _ArrayBinarySearch($_dates_fetes, $date) = -1 Then ;; si pas jour férié ni dimanche
$delta += 1 ; c'est un jour ouvré, donc on le compte
EndIf
WEnd
Return($delta)
EndFunc
; ajoute ou retranche N jours ouvrés à une date exprimée sous forme AAAA/MM/JJ
Func _JoursOuvresPlusN($date, $jours)
Local $d1, $dow, $direct
Select
Case $jours > 0
$direct = 1
Case $jours < 0
$direct = -1
Case Else
Return($date)
EndSelect
$jours = Abs($jours)
$d1 = StringSplit($date, '/-')
$dow = _DateToDayOfWeekISO($d1[1], $d1[2], $d1[3]) - 1
Do
$date = _DateAdd('D', $direct, $date) ; date +/- 1
$dow += $direct ; jour de la semaine +/- 1
If $dow < 0 Then $dow += 7
$d1 = StringLeft($date, 4) ; on vérifie s'il y a changement d'année
If $_annee_fetes <> $d1 Then ; si oui, on calcule les fêtes mobiles de la nouvelle année
$_annee_fetes = $d1
_DateFetesMobiles($_annee_fetes)
EndIf
If Mod($dow, 7) <> 6 And _ArrayBinarySearch($_dates_fetes, $date) = -1 Then ;; si pas dimanche ni jour férié
$jours -= 1 ; c'est un jour ouvré, donc on le décompte
EndIf
Until $jours = 0
Return($date)
EndFunc
; calcule la date de Pâques AAAA/MM/JJ pour l'année passée en paramètre, numérique ou string au format AA ou AAAA
Func _EasterDate($y)
Local $_y, $_g, $_s, $_x, $_z, $_d, $_e, $_n, $_j, $_m
$_y = Int(Number($y))
If $_y <= 99 And $_y >= 0 Then
$_y += 2000
EndIf
If $_y < 1592 Then
Return(SetError(1, 0, ""))
EndIf
$_g = Mod($_y, 19) + 1
$_s = Int($_y / 100) + 1
$_x = Int(3 * $_s / 4) - 12
$_z = Int((8 * $_s + 5) / 25) - 5
$_d = Int(5 * $_y / 4) - $_x - 10
$_e = Mod(11 * $_g + 20 + $_z - $_x, 30)
If ($_e = 25 And $_g > 11) Or $_e = 24 Then
$_e += 1
EndIf
$_n = 44 - $_e
If $_n < 21 Then
$_n += 30
EndIf
$_j = $_n + 7 - Mod($_d + $_n, 7)
If $_j > 31 Then
$_j -= 31
$_m = 4
Else
$_m = 3
EndIf
Return(StringFormat("%04i/%02i/%02i", $_y, $_m, $_j))
EndFunc
;; Met à jour la table des jours fériés mobiles en fonction de l'année
Func _DateFetesMobiles($y)
Local $_d
Local Const $fetesConst[21] = [ _ ;********** fêtes mobiles calculées au vol
"", _ ; lundi de Pâques ; index 0 (ne pas déplacer)
"", _ ; Ascension ; index 1 (ne pas déplacer)
"", _ ; lundi de Pentecôte ; index 2 (ne pas déplacer) voir notes
"", _ ; les 10 entrées qui suivent peuvent être employées pour des besoins spécifiques
"", _
"", _
"", _
"", _
"", _
"", _
"", _
"", _
"", _ ;********** fêtes fixes
$y & "/01/01", _ ; Jour de l'an
$y & "/05/01", _ ; Fête du travail
$y & "/05/08", _ ; Fête de la Victoire 1945
$y & "/07/14", _ ; Fête Nationale
$y & "/08/15", _ ; Assomption
$y & "/11/01", _ ; Toussaint
$y & "/11/11", _ ; Armistice 1918
$y & "/12/25"] ; Noël
$_d = _EasterDate($y)
$_dates_fetes = $fetesConst
$_dates_fetes[0] = _DateAdd('d', 1, $_d) ;; lundi de Pâques
$_dates_fetes[1] = _DateAdd('d', 39, $_d) ;; Ascension
If ($y < "2005") Or ($y > "2007") Then
$_dates_fetes[2] = _DateAdd('d', 50, $_d) ;; lundi de Pentecôte, sauf quand il a été décrété non férié ... Pffft !
EndIf
$_dates_fetes = _ArrayUnique($_dates_fetes, 1) ;; dédoublonnement. L'index [0] contient la dimension (ce qui est un choix débile)
_ArraySort($_dates_fetes, 1) ;; tri descendant : les dates "surnagent" ;-)
ReDim $_dates_fetes[_ArraySearch($_dates_fetes, "") - 1] ;; on enlève "" et la dimension, valeurs parasites
_ArrayReverse($_dates_fetes)
EndFunc