Aller au contenu

[TUTO] 🗓 Récupérer le jour de la semaine en Skript (L'algorithme de Zeller 🤓)


Messages recommandés

Posté(e)

Introduction
Hello les Skripteurs!! 👋
Je vous propose ici un tutoriel complet et  un Skript prêt à l’emploi en bas de page.
Ce tutoriel concerne une problématique qui manque cruellement de doc claire sur les forums de Skript en général:

Citation

Comment récupérer le jour de la semaine (lundi, mardi, etc.) en Skript ?

L’idée m’est venue en aidant un membre (coucou @Mamadoug 😄) qui voulait déclencher un évènement uniquement les week-end. Cependant, Skript ne propose pas d'expression native pour ça.
Mais pas de panique, on va utiliser un peu de logique et un algorithme fiable et on va y aller par étape.
 

Contexte
Skript propose une expression now pour récupérer la date actuelle, mais il n’existe aucun moyen direct de faire une condition telle que :

# output an error: Can't understand this condition: 'now is 'Monday''
if now is "Monday":

Cette condition n'est pas comprises par Skript, ce qui est très frustrant quand on veut faire une action selon le jour de la semaine
 

Étape 1 – Comprendre ce qu’on a : l'expression now (Skript Hub - Documentation)
Skript implémente l'expression now, qui donne l’instant actuel (avec jour, mois, année, heure, minute).
Mais il ne donne pas le jour de la semaine directement comme tu peux le voir dans l'output ci-dessous....

Citation

# output: 12/07/2025 00:11
send "%now formatted as "dd/M/yy HH:MM z"%" to sender 

👉 On a donc besoin de transformer now en quelque chose qu’on peut analyser... du texte par exemple.


Étape 2 – Obtenir les composantes de la date
La date donnée par now ressemble à ça : 12/07/2025 00:11
On crée une fonction formatDate() qui transforme/découpe ce texte en une liste : [12, 07, 2025, 00, 11] -> [jour, mois, année, heure, minute]

set {_date::*} to "%{_d}%" split by "/"

Cela nous permet de séparer jour, mois, année, ce qui est indispensable pour la suite.

Étape 3 – Ajouter une fonction modulo, absente de Skript...

Pour certains calculs, on a besoin d’un reste de division euclidienne, qu’on appelle modulo.

Citation

Exemple: 19 mod 7 = 5, parce que 19 divisé par 7 donne 2, et il reste 5

Or, Skript ne possède pas de fonction native modulo()... Donc on doit la créer nous-mêmes :

# Merci Yghore https://skript-mc.fr/forum/topic/16351-skript-modulo/#findComment-131599
function modulo(n1: number, n2: number) :: number:
	set {_divise} to round down ({_n1} / {_n2})
	set {_multiple} to {_n2} * {_divise}
	set {_modulo} to ({_n1} - {_multiple})
	return {_modulo}

Je ne vais pas détailler le fonctionnement du modulo Ici car cela peut faire l'objet d'un autre post.
En savoir plus sur le modulo : Modulo (opération) — Wikipédia
Cette fonction sera indispensable dans l’étape suivante, lorsqu’on fera un calcul plus avancé sur la date. 😉

...et merci @Yghore pour le snippet 🙂
 

Étape 4 – Utiliser les maths : l'algorithme de Zeller Pourquoi ?
Puisqu’on n’a pas de fonction pour trouver le jour de la semaine directement dans Skript,
on fait comme les anciens : on le calcule mathématiquement à partir de la date..
Ce qui donne cette formule pour notre calendrier géorgien:

image.png.ca797b2ca72db15d2f99b6af37e013e7.png.d9cc22534ced7cc9047f35998c1b4db4.png
L'idée de Zeller : On prend le jour (q), le mois (m), et "l’année" (K), et on fait des opérations mathématiques.
Ici en fonction de la valeur de h, nous pouvons en déduire du jours de la semaine car cette formule donne le jour de la semaine
sous forme d’un nombre de 0 à 6 
:

Pour chaque valeur de h, interpréter de la manière suivante :
0 : "Saturday"  # Samedi
1 : "Sunday"    # Dimanche
2 : "Monday"    # Lundi
3 : "Tuesday"   # Mardi
4 : "Wednesday" # Mercredi
5 : "Thursday"  # Jeudi
6 : "Friday"    # Vendredi

Nous avons heureusement implémenté notre fonction modulo() plus tôt, et cela va nous servir à réécrire cette formule en Skript!
Donc la formule énoncée plus haut donnerai quelque chose comme ça:

# Uses the Zeller's Congruence algorithm to calculate the day of the week
# Ref: https://fr.wikipedia.org/wiki/D%C3%A9termination_du_jour_de_la_semaine
if {_month} is "January":
set {_month} to 13
    set {_year} to {_year} - 1
else if {_month} is "February":
    set {_month} to 14
    set {_year} to {_year} - 1
else:
    set {_month} to {_month} + 1
set {_k} to modulo({_year}, 100)
set {_j} to {_year} / 100
set {_f} to {_day} + (13 * ({_month} + 1)) / 5 + {_k} + {_k} / 4 + {_j} / 4 - (2 * {_j})
set {_f} to modulo({_f}, 7)
# à partir de là, {_f} contient notre jour de la semaine de manière numérique

Je ne vais pas détailler plus loin, si vous voulez en savoir plus au niveau de la transcription de cette formule mathématique
en langage de programmation, voici une ressource qui vous sera utile: 
Zeller's Congruence | Find the Day for a Date - GeeksforGeeks

 

Étape 5 – On écrit getDayOfTheWeek(d: date)
Cette fonction prend la date, applique l’algorithme de Zeller, et retourne une chaîne de caractères : "Monday", "Tuesday", ..., "Sunday"
Maintenant, on peut poser une vraie question lisible :

if getDayOfTheWeek(now) is "Sunday":

Nous avons donc codé cette formule dans la fonction getDayOfTheWeek() qui prend en paramètre une date et qui retourne en fonction de la valeur de h, le jour de la semaine en anglais.

Révélation
# Uses the Zeller's Congruence algorithm to calculate the day of the week
# Ref: https://fr.wikipedia.org/wiki/D%C3%A9termination_du_jour_de_la_semaine
function getDayOfTheWeek(d: date) :: string:
    set {_date::*} to formatDate({_d})
    set {_day} to {_date::1}
    set {_month} to {_date::2}
    set {_year} to {_date::3}
    if {_month} is "January":
        set {_month} to 13
        set {_year} to {_year} - 1
    else if {_month} is "February":
        set {_month} to 14
        set {_year} to {_year} - 1
    else:
        set {_month} to {_month} + 1
    set {_k} to modulo({_year}, 100)
    set {_j} to {_year} / 100
    set {_f} to {_day} + (13 * ({_month} + 1)) / 5 + {_k} + {_k} / 4 + {_j} / 4 - (2 * {_j})
    set {_f} to modulo({_f}, 7)
    if {_f} is 0:
        return "Saturday"
    else if {_f} is 1:
        return "Sunday"
    else if {_f} is 2:
        return "Monday"
    else if {_f} is 3:
        return "Tuesday"
    else if {_f} is 4:
        return "Wednesday"
    else if {_f} is 5:
        return "Thursday"
    else:
        return "Friday"

 


Bonus - Une commande pour tester directement

Pour finir, j’ai codé une petite commande pratique:
Elle permet d’afficher le jour de la semaine actuel, formaté proprement avec l’heure et la date.
Commande à utiliser : /now
Elle affiche par exemple :

Saturday 12/07/2025 00:11

Pratique pour tester rapidement le fonctionnement de la fonction getDayOfTheWeek() ! 😉

Voilà, j’espère que ce tutoriel vous aura été utile et qu’il vous aura permis d’apprendre quelque chose au passage 🙂
Notamment sur comment contourner certaines limites de Skript en s’appuyant sur un peu de logique mathématique (merci Zeller 😄).

L’idée était simple à la base, mais demandait une mise en œuvre un peu plus technique, désormais à votre portée !
Le code proposé est plug-and-play, libre à vous de l’adapter à vos besoins (event spécial, message du jour, gestion hebdomadaire, etc...).

Et si vous souhaitez aller plus loin (exécution à heure fixe, détection de jours fériés, commandes manuelles...), je serai ravi de vous filer un coup de main !

Bref... Bon dev à tous… et bon week-end...  si c’en est un 😉

Ah... et... comme promis... voici le Skript dans son entièreté (ne me remerciez pas):

Révélation
# Cette commande affiche la date actuelle et le jour de la semaine
# Output example: Saturday 12/07/2025 00:11
command /now:
    trigger:
        set {_date} to now formatted as "dd/MM/yy HH:MM z"
        send "%getDayOfTheWeek({_date})% %{_date}%" to sender

# This function returns the day of the week for a given date
# Uses the Zeller's Congruence algorithm to calculate the day of the week
# Ref: https://fr.wikipedia.org/wiki/D%C3%A9termination_du_jour_de_la_semaine
function getDayOfTheWeek(d: date) :: string:
    set {_date::*} to formatDate({_d})
    set {_day} to {_date::1}
    set {_month} to {_date::2}
    set {_year} to {_date::3}
    if {_month} is "January":
        set {_month} to 13
        set {_year} to {_year} - 1
    else if {_month} is "February":
        set {_month} to 14
        set {_year} to {_year} - 1
    else:
        set {_month} to {_month} + 1
    set {_k} to modulo({_year}, 100)
    set {_j} to {_year} / 100
    set {_f} to {_day} + (13 * ({_month} + 1)) / 5 + {_k} + {_k} / 4 + {_j} / 4 - (2 * {_j})
    set {_f} to modulo({_f}, 7)
    if {_f} is 0:
        return "Saturday"
    else if {_f} is 1:
        return "Sunday"
    else if {_f} is 2:
        return "Monday"
    else if {_f} is 3:
        return "Tuesday"
    else if {_f} is 4:
        return "Wednesday"
    else if {_f} is 5:
        return "Thursday"
    else:
        return "Friday"

# Returns a formatted date as a list of strings
# Format: [day, month, year, hour, minute]
# {_value::1} = day, {_value::2} = month, {_value::3} = year, {_value::4} = hour, {_value::5} = minute
# Ref: https://skript-mc.fr/forum/topic/14832-r%C3%A9cup%C3%A9r%C3%A9-des-informations-sur-une-date-novice/
function formatDate(d: date) :: objects: 
    set {_date::*} to "%{_d}%" split by "/"
    set {_day} to {_date::1}
    set {_month} to {_date::2}
    set {_t::*} to "%{_date::3}%" split by " "
    set {_year} to {_t::1}
    set {_time::*} to {_t::2} split by ":"
    set {_hour} to {_time::1}
    set {_minute} to {_time::2}
    add {_day} to {_value::*}
    add {_month} to {_value::*}
    add {_year} to {_value::*}
    add {_hour} to {_value::*}
    add {_minute} to {_value::*}
    return {_value::*}

# Skript modulo function
# https://skript-mc.fr/forum/topic/16351-skript-modulo/#findComment-131599
function modulo(n1: number, n2: number) :: number:
	set {_divise} to round down ({_n1} / {_n2})
	set {_multiple} to {_n2} * {_divise}
	set {_modulo} to ({_n1} - {_multiple})
	return {_modulo}

# Ressources mention spéciale:
# date() function : https://skripthub.net/docs/?id=2116
# utilisation des fonction : https://skripthub.net/tutorials/9

 

time.sk

  • J'aime 1
  • 3 semaines après...
  • 1 mois après...
Posté(e)

Salut, sinon on peux juste faire ceci: 

now formatted as "EEEE" #Version complète > "Monday"
  OU
now formatted as "EEE" #Version plus compact > "Mon"

Au lieu de s'embêter avec des fonctions ^^

 

Bien le bonsoir,

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.