IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Téléchargé 34 fois
Vote des utilisateurs
0 
0 
Détails
Licence : Libre
Mise en ligne le 27 août 2013
Plate-formes : Linux, Mac, Windows
Langue : Français
Référencé dans
Navigation

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

Avatar de fred1599
Expert éminent 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
Expert éminent 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
Expert éminent 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
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
Expert éminent sénior 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
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
Expert éminent sénior 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
Avatar de thibaut.m
Candidat au Club https://www.developpez.com
Le 18/02/2021 à 12:05
Bonjour, je réponds à cette discussions très tardivement, mais je suis tombé dessus car j'avais besoin d'une façon de calculer la différence entre 2 jours.

Voici mon problème :

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
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 ((parse(date_1)) - (parse(date_2))).days

def vac():
    date_today=time.strftime('%d/%m/%Y',time.localtime())
    #recuperation des dates vacances
    tab_vac = pd.read_csv('vacances.csv' , delimiter =';', encoding='ISO-8859-1')
    tab_vac = tab_vac.dropna(how='all')  #Netoyage du tableau
    tab_vac = tab_vac.dropna(axis =1, how='all') #Netoyage du tableau
    long = len(tab_vac)
    for n in range(1,long):
        n_days = days_diff(DATE_1,  DATE_2)
        print(n_days)
        if n_days >= 0:
            print("oui")

    
DATE_1 = '25/05/1955'
DATE_2 = '28/08/2013'           
n_days = days_diff(DATE_1,  DATE_2) # 21280 days
print(n_days)

vac()
Voici ma réponse :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-21280

  File "C:\Users\meine\Desktop\PAUL\AppliPython\prevV1.py", line 115, in <module>
    vac()

  File "C:\Users\meine\Desktop\PAUL\AppliPython\prevV1.py", line 29, in vac
    n_days = days_diff(DATE_1,  DATE_2)

  File "C:\Users\meine\Desktop\PAUL\AppliPython\prevV1.py", line 19, in days_diff
    return ((parse(date_1)) - (parse(date_2))).days

  File "C:\Users\meine\Desktop\PAUL\AppliPython\prevV1.py", line 15, in parse
    return date(y, m, d)

TypeError: 'str' object is not callable
Donc j'appelle la fonction dans le programme principal cela fonctionne très bien, malheureusement quand je l'itére dans une autre fonction cela ne focntionne pas ( et pourtant je lui donne les même variable pour le moment donc je ne comprends vraiment pas pourquoi.

Avez-vous une idée d'où cela pourrait provenir ?
Merci pour votre aide.
Avatar de tyrtamos
Expert éminent https://www.developpez.com
Le 18/02/2021 à 15:35
Bonjour,

L'erreur dit que "date" est une chaîne de caractères, et qu'on ne peut donc pas l'utiliser comme une fonction. Si "date" est à l'origine une fonction du module "datetime" (par exemple), le code doit aussi présenter une variable str appelée "date" qui la cache.
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.