Différence entre deux dates

Présentation
Déterminer le nombre de jours entre deux dates.

Le paramètre de la date est du type 22/05/1955 dont le type est une chaine de caractères.

La fonction parse pour analyser la chaine de caractères et retourner un objet date
La fonction days_diff pour déterminer le nombre de jours entre deux dates

Téléchargement
Compatibilité
Linux Mac Windows
0  0 
Téléchargé 84 fois Voir les 7 commentaires
Détails
Avatar de fred1599
Expert confirmé
Voir tous les téléchargements de l'auteur
Licence : Libre
Date de mise en ligne : 27 août 2013




Avatar de fred1599 fred1599 - Expert confirmé https://www.developpez.com
le 27/08/2013 à 10:11
Bonjour,

Je vous propose un nouvel élément à utiliser : Différence entre deux dates

Déterminer le nombre de jours entre deux dates.

Le paramètre de la date est du type 22/05/1955 dont le type est une chaine de caractères.

La fonction parse pour analyser la chaine de caractères et retourner un objet date

La fonction days_diff pour déterminer le nombre de jours entre deux dates

Qu'en pensez-vous ?
Avatar de fred1599 fred1599 - Expert confirmé https://www.developpez.com
le 27/08/2013 à 11:50
Salut tyrtamos,

En effet c'est une bonne idée

Si j'ai un peu de temps, je vais déjà penser à ta 1ère proposition...

Merci pour tes commentaires.

Bonne journée.
Avatar de fred1599 fred1599 - Expert confirmé https://www.developpez.com
le 27/08/2013 à 14:16
Voilà pour le nombre de jours ouvrables, dis moi ce que t'en penses

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from datetime import date,  timedelta
from calendar import SATURDAY,  SUNDAY
 
def parse(my_date):
    d, m, y = map(int, my_date.split('/'))
    return date(y, m, d)
 
def days_diff(date_1, date_2):
    """date of type 15/05/1972"""
    return abs((parse(date_1) - parse(date_2)).days)

def work_days(date_1,  n):
    """
    numbers of days of work
    n -> result of function days_diff
    """
    somme = 0
    info = parse(date_1)
    for n in range(n):
        days = info + timedelta(days=n)
        if days.weekday() == SATURDAY or days.weekday() == SUNDAY:
            somme += 1
    return n - somme
    

DATE_1 = '25/5/1955'
DATE_2 = '28/8/2013'
n_days = days_diff(DATE_1,  DATE_2) # 21280 days
print(work_days(DATE_1, n_days)) # 15199 days working
Avatar de tyrtamos tyrtamos - Expert éminent https://www.developpez.com
le 28/08/2013 à 8:55
Bonjour,

Voilà comment j'écrirais le calcul des jours ouvrés:

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from datetime import date, timedelta

def ecartdates_swe(D1, D2):
    """calcule le nombre de jours entre D1 et D2 sans les samedis+dimanches
       D2 doit être postérieur ou égal à D1
       D1 et D2 sont donnés en chaine selon le format: "j/m/aaaa"
    """
    d1 = date(*map(int, D1.split('/')[::-1]))
    d2 = date(*map(int, D2.split('/')[::-1]))
    unjour = timedelta(1)
    n = 0
    while d1<d2:
        if d1.weekday() not in [5, 6]:
            n += 1
        d1 += unjour
    return n
Exemple d'utilisation:

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from time import clock

joursemaine = [u"lundi", u"mardi", u"mercredi", u"jeudi", u"vendredi", u"samedi", u"dimanche"]

# conversion 'j/m/aaaa' ==> [aaaa, m, j] ==> objet date
faitdate = lambda D: date(*map(int, D.split('/')[::-1]))

D1 = '25/5/1955'
D2 = '28/8/2013'

t = clock()
n = ecartdates_swe(D1, D2)
t = clock()-t

d1 = faitdate(D1)
d2 = faitdate(D2)

print u"Nombre total de jours entre le %s %s et le %s %s: %d" % (joursemaine[d1.weekday()], D1, joursemaine[d2.weekday()], D2, (d2-d1).days)
print u"Idem sans les samedis+dimanches: %d" % (n,) 
print u"Durée du calcul: %.3f seconde(s)" % (t,)
Ce qui affiche:

Nombre total de jours entre le mercredi 25/5/1955 et le mercredi 28/8/2013: 21280
Idem sans les samedis+dimanches: 15200
Durée du calcul: 0.009 seconde(s)
Le calcul proposé parait un peu rustique (on teste chaque jour), mais il est en fait très rapide: 9/1000 seconde pour tester les 21280 jours!

De plus, on peut facilement l'adapter à la prise en compte d'une liste supplémentaire de jours non travaillés, quelqu'en soit la raison (jours fériés, congés, RTT, etc...): prévoir cette liste comme 2ème argument et ajouter un test supplémentaire dans la boucle while.

Mais pour les samedis+dimanches, on pourrait cependant proposer un algorithme plus subtil, dont les principes seraient les suivants:

- on convertit les chaines D1 et D2 en "date" d1 et d2
- on calcule le nb total de jours entre d1 et d2: (d2-d1).days
- s'il est <=7 jours: on teste chaque jour et on renvoie le résultat.
- sinon:
- on incrémente d1 et on teste jusqu'à obtenir un lundi. On garde le résultat: nombre de jours et nombre de samedi+dimanche (0, 1 ou 2).
- on décrémente d2 et on teste jusqu'à obtenir un lundi. On garde le résultat: nombre de jours et nombre de samedi+dimanche (0, 1 ou 2).
- le nombre de jours entre les nouveaux d1 et d2 divisé par 7 (ça tombera juste) représente donc le nombre de semaines: en le multipliant par 2, on a donc facilement le nombre de samedis+dimanches.
- on en déduit le nombre de jours sans week-end recherché

Si ça t'intéresse, je peux te proposer un code qui fait ça.

NB: Si on neutralise les samedis-dimanches et pas seulement les dimanches, il s'agit de jours ouvrés (https://fr.wikipedia.org/wiki/Jour_ouvr%C3%A9) et non de jours ouvrables (https://fr.wikipedia.org/wiki/Jour_ouvrable): ceux qui ne travaillent pas le samedi feront facilement la différence!
Avatar de wiztricks wiztricks - Modérateur https://www.developpez.com
le 28/08/2013 à 13:39
Salut,

La classe datetime inclue la méthode .strptime a laquelle on passe le format de la représentation de la date.
En écrivant:
Code : Sélectionner tout
d1=datetime.strptime(D1, '%d/%m/%Y').date()
Plutôt que:
Code : Sélectionner tout
d1 = date(*map(int, D1.split('/')[::-1]))
Le code est plus lisible et plus compact puisqu'on pourra se passer de la ligne de commentaire devant "documenter" ce que ça fait.

Pour traiter les questions de calendrier et d'agenda, la bibliothèque externe dateutil est assez performante et simple a utiliser.

- W
PS: Je ne vois pas l’intérêt a passer du temps a refaire ce qui existe déjà sauf pour "apprendre" ou l’améliorer de façon notable. De plus, si vous ne prenez pas le temps de comprendre et utiliser ce qui existe déjà, pourquoi espérer que vos posts soient plus "utilises"?
Avatar de tyrtamos tyrtamos - Expert éminent https://www.developpez.com
le 28/08/2013 à 14:34
Bonjour wiztricks,

Merci pour le lien, je ne connaissais pas: grosse bibliothèque, doc longue et en anglais: je crois que je l'utiliserai quand je ne pourrai pas faire autrement.

Mais oui, c'est amusant de coder soi-même. Même si on fait des bugs de temps en temps, on apprend des tas de choses, et au moins, on comprend ce qu'on utilise.

Et merci pour tes encouragements...
Avatar de wiztricks wiztricks - Modérateur https://www.developpez.com
le 28/08/2013 à 16:08
Salut,

Citation Envoyé par tyrtamos Voir le message
Mais oui, c'est amusant de coder soi-même. Même si on fait des bugs de temps en temps, on apprend des tas de choses, et au moins, on comprend ce qu'on utilise.
Il y a une différence entre ce qu'on peut faire dans son coin pour apprendre, s'amuser, découvrir, .... et des codes proposes aux autres pour qu'ils gagnent du temps, ne tombent pas dans certains pièges,...

- W
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.