Outils pour utilisateurs

Outils du site


calcul_de_dates

Ceci est une ancienne révision du document !


Calcul de dates

Date du jour (de l'ordinateur)

import time
 
def cejour():
    """cejour(): donne la date du jour sous le format 'jj/mm/aaaa' (ex: '10/03/2008')"""
    return time.strftime('%d/%m/%Y')
 
# exemple d'utilisation: affiche une date comme "10/03/2008"
print cejour()

Dit si l'année est bissextile

Une année bissextile est une année qui a un 29 février en plus et donc, comporte 366 jours au lieu de 365.

Réference: http://fr.wikipedia.org/wiki/Ann%C3%A9e_bissextile

Voici la fonction la plus courte (une ligne). On lui donne l'année en nombre entier (exemple: a=2009), et elle renvoie True ou False selon le résultat.

def bissextile(a):
    """Dit si l'année donnée est bissextile ou non"""
    return (a%4==0 and a%100!=0) or a%400==0

On pourrait d'ailleurs en faire une fonction lambda:

bissextile = lambda a: (a%4==0 and a%100!=0) or a%400

Exemple d'utilisation:

print bissextile(2008)  # affiche: True
print bissextile(2009)  # affiche: False
print bissextile(2000)  # affiche: True
print bissextile(3000)  # affiche: False

On peut chercher un codage plus rapide. En effet, avec une année au hasard, elle a en gros 75% de chance de ne pas être bissextile. Il faudrait donc pouvoir répondre plus rapidement dans ce cas, c'est à dire avec un simple test. Voilà une solution:

def bissextile(a):
    """Dit si l'année donnée est bissextile ou non"""
    if a%4!=0:
        return False
    if a%100==0 and a%400!=0:
        return False
    return True

Le temps gagné n'est pas terrible: environ 5%. mais c'est toujours ça…

Cependant, lorsqu'on doit appeler cette condition dans une autre fonction, il est probablement meilleur d'utiliser directement la condition monoligne pour éviter l'appel de la fonction.

Avec cette correction d'année bissextile, il restera encore un écart de 3 jours tous les 10000 ans entre notre calendrier et le mouvement des planètes. Bon. On verra ça le moment venu…:-D

Donne le nombre de jours de l'année

def nbjoursan(a):
    """Donne le nombre de jours de l'année"""
    if (a%4==0 and a%100!=0) or a%400==0: # bissextile?
        return 366
    else:
        return 365

Exemples d'utilisation:

print nbjoursan(2008)  # affiche: 366
print nbjoursan(2009)  # affiche: 365

Donne le nombre de jours d'un mois pour une année donnée

def nbjoursmois(m,a):
    """Donne le nombre de jours du mois m de l'année a"""
    nj = (0,31,28,31,30,31,30,31,31,30,31,30,31)[m]
    if m==2 and ((a%4==0 and a%100!=0) or a%400==0): # m=février et a=bissextile?
        return nj + 1
    return nj

Dans ce code, la liste des nombres de jours des mois nj commence à zéro pour que janvier soit à l'index 1 et pas 0. Ceci pour éviter de décrémenter m pour trouver l'index.

Exemples d'utilisation:

print nbjoursmois(2,2007)  # affiche: 28
print nbjoursmois(2,2008)  # affiche: 29
print nbjoursmois(7,2008)  # affiche: 31
print nbjoursmois(9,2008)  # affiche: 30

Donne le numéro du jour de l'année

def numjouran(d):
    """Donne le numéro du jour dans l'année de la date d=[j,m,a] (1er janvier = 1, ...)"""
    j, m, a = d
    if ((a%4==0 and a%100!=0) or a%400==0):  # bissextile?
        return (0,31,60,91,121,152,182,213,244,274,305,335,366)[m-1] + j
    else:
        return (0,31,59,90,120,151,181,212,243,273,304,334,365)[m-1] + j

Exemple d'utilisation:

d = [10, 12, 2008]
print numjouran(d) #  affiche 345
d = [10, 12, 2009]
print numjouran(d) #  affiche 344

Donne la date qui est le nième jour de l'année

C'est la fonction inverse de la fonction précédente numjouran(d)

def datenumjouran(n,a):
    """Donne la date d=[j,m,a] qui est le nième jour de l'année a"""
    if ((a%4==0 and a%100!=0) or a%400==0):  # bissextile?
        jm = (0,31,60,91,121,152,182,213,244,274,305,335,366)
    else:
        jm = (0,31,59,90,120,151,181,212,243,273,304,334,365)
    for m in range(1,13):
        if jm[m]>=n:
            return [n-jm[m-1], m, a]

Exemple d'utilisation:

print datenumjouran(345,2008)  #  affiche [10, 12, 2008]

Dit si une date est postérieure ou égale à une autre

def postdate(D1,D2):
    """postdate(D1,D2): dit si une date D2 'j/m/a' est postérieure ou égale à une autre date D1 'j/m/a'"""
    L1=D1.split('/')
    L2=D2.split('/')
    if int(L2[2])>int(L1[2]):
        return True
    elif int(L2[2])==int(L1[2]):
        if int(L2[1])>int(L1[1]):
            return True
        elif int(L2[1])==int(L1[1]):
            if int(L2[0])>=int(L1[0]):
                return True
    return False
 
# Exemple d'utilisation: affiche True, True et False
print postdate("10/3/2008","5/5/2008")
print postdate("10/3/2008","10/3/2008")
print postdate("5/5/2008","10/3/2008")

Nombre de jours entre 2 dates quelconques

Utilise les fonctions suivantes définies plus haut:

  • bissextile(a): dit si l'année est bissextile
  • nbjoursan(a): donne le nombre de jours de l'année (365 ou 366)
  • numjouran(D): donne le numéro du jour dans l'année (1er janvier = 1, …)
  • postdate(D1,D2): dit si la date D2 est postérieure ou égale à D1
def diffdate(D1,D2):
    """diffdate(D1,D2): nombre de jours entre 2 dates ('j/m/a'), >=0 si D2>=D1, <0 sinon"""
    L1=D1.split('/')
    L2=D2.split('/')
    a1=int(L1[2])
    a2=int(L2[2])
    x1=numjouran(D1)
    x2=numjouran(D2)
    if postdate(D1,D2):
        # D2 est postérieure a D1: retour d'un nb >=0
        nk=x2-x1
        for ak in range(a1,a2):
            nk=nk+nbjoursan(ak)
        return nk
    else:
        # D2 est postérieure a D1: retour d'un nb >=0
        nk=x2-x1
        for ak in range(a2,a1):
            nk=nk-nbjoursan(ak)
        return nk
 
# Exemple d'utilisation: renvoie 56, 0, -56, 309 et 365
print diffdate("10/3/2008","5/5/2008")
print diffdate("10/3/2008","10/3/2008")
print diffdate("5/5/2008","10/3/2008")
print diffdate("5/5/2008","10/3/2009")
print diffdate("5/5/2008","5/5/2009")

Donne la date postérieure ou antérieure de n jours à une date donnée

Utilise les fonctions suivantes définies plus haut:

  • bissextile(a): dit si l'année est bissextile
  • nbjoursan(a): donne le nombre de jours de l'année (365 ou 366)
  • numjouran(D): donne le numéro du jour dans l'année (1er janvier = 1, …)
  • datenumjouran(n,an): donne la date qui est le nième jour de l'année

Si n est >0, la date cherchée sera postérieure de n jours à la date donnée.

def adddate(D,n):
    """adddate(D,n): donne la date postérieure de n jours (n>=0) ou antérieure de n jours (n<0) à la date D 'j/m/a'"""
    L=D.split('/')
    ak=int(L[2])
    if n>=0:
        nk=numjouran(D)+n
        while nk>nbjoursan(ak):
            nk=nk-nbjoursan(ak)
            ak=ak+1
        return datenumjouran(nk,ak)
    else:
        nk=abs(n)+nbjoursan(ak)-numjouran(D)
        while nk>=nbjoursan(ak):
            nk=nk-nbjoursan(ak)
            ak=ak-1
        return datenumjouran(nbjoursan(ak)-nk,ak)
 
# Exemple d'utilisation: renvoie 11/03/2008, 09/03/2008, 10/04/2008, 10/03/2009, 10/03/2007
print adddate("10/3/2008",1)
print adddate("10/3/2008",-1)
print adddate("10/3/2008",31)
print adddate("10/3/2008",365)
print adddate("10/3/2008",-366)

Trouver le jour de la semaine d'une date donnée

Utilise les fonctions suivantes définies plus haut:

  • bissextile(a): dit si l'année est bissextile
  • numjouran(D): donne le numéro du jour dans l'année (1er janvier = 1, …)

La 1ère fonction numjoursem(D) renvoie le jour de semaine sous forme d'un chiffre (lundi=1, …, dimanche=7)

La seconde fonction joursem(D) renvoie le jour de semaine sous forme de chaîne de caractère ('lundi', …)

def numjoursem(D):
    """numjoursem(D): donne le numéro du jour de la semaine d'une date D 'j/m/a' (lundi=1, ...)"""
    L=D.split('/')
    an=int(L[2])-1
    j=(an+(an//4)-(an//100)+(an//400)+numjouran(D)) % 7
    if j==0: j=7
    return j
 
def joursem(D):
    """joursem(D): donne le jour de la semaine d'une date D 'j/m/a' ('lundi' pour lundi, ...)"""
    return ('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche')[numjoursem(D)-1]
 
# Exemple d'utilisation: renvoie 1, 7, 2, lundi, dimanche, mardi
print numjoursem("10/3/2008")
print numjoursem("23/3/2008")
print numjoursem("1/1/2008")
 
print joursem("10/3/2008")
print joursem("23/3/2008")
print joursem("1/1/2008")

Trouve la date du lundi d'une semaine qui contient une date donnée

Utilise les fonctions suivantes définies plus haut:

  • numjoursem(D): donne le numéro du jour de semaine (lundi=1, …)
  • adddate(D,n): donne la date postérieure ou antérieure de n jours à une date donnée
def lundi(D):
    """lundi(D): trouve la date du lundi d'une semaine qui contient la date D 'j/m/a'"""
    return adddate(D,-numjoursem(D)+1)
 
# Exemple d'utilisation: renvoie 10/03/2008, 17/03/2008, 31/12/2007
print lundi("10/3/2008")
print lundi("23/3/2008")
print lundi("1/1/2008")

Dit si une date tombe un week-end (samedi ou dimanche)

Utilise la fonction suivante définie plus haut:

  • numjoursem(D): donne le numéro du jour de semaine (lundi=1, …)
def estweekend(D):
    """estweekend(D): dit si une date D donnée 'j/m/a' correspond à un samedi ou un dimanche"""
    if numjoursem(D)>5:
        return True
    else:
        return False
 
# Exemple d'utilisation: renvoie False, True, False
print estweekend("10/3/2008")
print estweekend("23/3/2008")
print estweekend("1/1/2008")

calcul_de_dates.1255332688.txt.gz · Dernière modification: 2009/10/12 09:31 de tyrtamos

Outils de la page