Bonjour,
je cherche à programmer cet exemple :
Nombre de jours 3
Date début : 29/11/2017
Date fin : 02/12/2017
=> 1 jour pour le mois 11
=> 2 jours pour le moi 12
comment je peux la développer en C# ?
merci de me guider.
Cordialement,
Bonjour,
je cherche à programmer cet exemple :
Nombre de jours 3
Date début : 29/11/2017
Date fin : 02/12/2017
=> 1 jour pour le mois 11
=> 2 jours pour le moi 12
comment je peux la développer en C# ?
merci de me guider.
Cordialement,
Bonjour,
Pas compris ce que tu voulais faire.
Cependant as tu regardé Datime.AddDays(...); et TimeSpan ?
Par ce que tu semble vouloir ajouter des jours, et faire une différence entre des dates... A savoir que la soustraction de 2 DateTime donne un TimeSpan.
J@ck.
Pas de réponse par MP, merci.
Penser au ça fait plaisir
Si j'ai bien compris ton problème, tu souhaites faire un algo te permettant, suivant une date de début et une date de fin, de compter le nombre de jours par mois qu'il y a entre les deux dates.
Un autre exemple serait :
C'est bien ça?Variables d'entrée :
Date début : 24/08/2017
Date fin : 2/12/2017
Résultat :
7 jours pour le mois 08
30 jours pour le mois 09
31 jours pour le mois 10
30 jours pour le mois 11
2 jours pour le mois 12
Je te propose ceci. Si quelqu'un à mieux ...
Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
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 $sdebut = "29/11/2017" $sfin = "02/12/2017" #$sdebut = "24/08/2017" #$sfin = "02/12/2017" $start = [datetime]::ParseExact($sdebut, "dd/MM/yyyy", $null) $end = [datetime]::ParseExact($sfin, "dd/MM/yyyy", $null) $currentDay = $start $currentLastDay = $currentDay while ($currentLastDay -lt $end) { $currentLastDay = (New-Object DateTime $currentLastDay.Year, $currentLastDay.Month, 01).AddMonths(1).AddDays(-1) if ($currentLastDay -gt $end) { $currentLastDay = $end } $Delta = ($currentLastDay - $currentDay).TotalDays Write-Host "$Delta jours pour le mois $($currentLastDay.Month) de l'année $($currentLastDay.Year)" $currentDay = $currentDay.AddDays($Delta) $currentLastDay = $currentLastDay.AddDays(1) }
Allez, à mon tour, c'est un peu bourrin mais ça marche :
Au suivant !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 static void Main(string[] args) { var from = new DateTime(2017, 2, 6); var to = new DateTime(2017, 5, 8); var daysByMonth = EnumerateDays(from, to) .GroupBy(d => d.Month) .Select(l => new Tuple<int, int>(l.First().Month, l.Count())); foreach (var i in daysByMonth) Console.WriteLine($"{i.Item1}:{i.Item2}"); } public static IEnumerable<DateTime> EnumerateDays(DateTime from, DateTime to) { for (var current = from; current <= to; current = current.AddDays(1)) yield return current; }
Mais lol. Je croyait être sur le forum PowerShell.
On peut voir le résultat Noxen ?
2:23
3:31
4:30
5:8
L'idée est d'extraire chaque jour entre les deux dates (j'ai dit que c'était bourrin ; mais à mon sens la charge de calcul et de mémoire est négligeable à moins de calculer sur des siècles), grouper par le mois et pour chaque groupe récupérer le mois et la taille du groupe dans un tuple ; à vous de voir comment vous voulez récupérer les données en sortie.
Il me semble que si tu reprend les dates de l’énoncée tu ne trouve pas les jours souhaités
Et quel est le résultat sur plus d'un ans stp ?Date début : 29/11/2017
Date fin : 02/12/2017
=> 1 jour pour le mois 11
=> 2 jours pour le moi 12
Bonjour,
Ma suggestion :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 static void Main(string[] args) { DateTime from = new DateTime(2017, 2, 6); DateTime to = new DateTime(2017, 2, 8); for(int m = from.Year * 12 + from.Month; m <= to.Year * 12 + to.Month; m++) { DateTime d = new DateTime(m / 12, m % 12, 1); // DateTime correspondant au premier jour du mois en cours DateTime end = d.AddMonths(1).AddDays(-1) < to ? d.AddMonths(1).AddDays(-1) : to; // d.AddMonths(1).AddDays(-1) correspond au dernier jour du mois en cours DateTime start = d > from ? d : from; int nbJours = (end - start).Days + 1; Console.WriteLine("{0}/{1} : {2}", d.Month, d.Year, nbJours); } Console.ReadLine(); }
François DORIN
Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
Site internet | Profils Viadéo & LinkedIn
---------
Page de cours : fdorin.developpez.com
---------
N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels
Sur le premier point : je n'avais pas fait attention au fait que la date de début était exclusive pour le calcul des jours (la date de fin est par contre inclusive).
Sur le second point : j'avoue que je n'ai pas réfléchie assez loin et pas pensé au regroupement sur l'année. Petit ajustement du coup :
Ce qui donne les résultats suivants pour les dates 29/11/2017 et 02/12/2020 (je voulais inclure une année bissextile) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 var daysByMonth = EnumerateDays(from.AddDays(1), to) .GroupBy(d => d.Year * 100 + d.Month) .Select(l => new Tuple<int, int>(l.First().Year * 100 + l.First().Month, l.Count()));
201711:1
201712:31
201801:31
201802:28
201803:31
201804:30
201805:31
201806:30
201807:31
201808:31
201809:30
201810:31
201811:30
201812:31
201901:31
201902:28
201903:31
201904:30
201905:31
201906:30
201907:31
201908:31
201909:30
201910:31
201911:30
201912:31
202001:31
202002:29
202003:31
202004:30
202005:31
202006:30
202007:31
202008:31
202009:30
202010:31
202011:30
202012:2
EDIT : ceci-dit je m'interroge sur la pertinence d'exclure le premier jour : si je dis que je travaille du 29/11/2017 au 02/12/2017 ça me fait quatre jours de travail, pas trois ; à voir quel est le contexte du demandeur.
Bonjour,
On est typiquement sur un exemple parfait du dérapage en couille de .NET
Ou comment transformer un langage puissant et performant en bouse infâme singeant JavaScript et PHP...
Le code de François Dorin est à peu de chose près celui que j'aurais écrit aussi.
Méthode "old school", fortement typée (le code est typé, pas seulement le binaire généré, donc lisible), et performant : on ne boucle pas inutilement sur des centaines de jours.
Le code de Noxen est celui que je blâme.
Méthode "nouveautés" C# rulez trop d'la balle. Code concis, lisible pour ceux qui arrivent à comprendre une requête Linq, typé uniquement à la compilation (moi ça me pique les yeux les "var" quand le type est déjà connu) et méga usine à gaz : on doit itérer sur tous les jours de l'interval pour faire le calcul.
En réalité, on aurait pu du coup en langage 100% non objet produit la même chose, au détail que ça aurait été encore plus simple et plus rapide : (à peu de chose près) :
Ça fait la même chose, sans instancier des milliers d'objets inutilement, mais ça reste bien moins performant que la méthode de François, qui est la seule qui respecte les bonnes pratiques de développement.
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 int annee = 0, mois = 0, nbjours = 0; DateTime debut = new DateTime(2017, 2, 6); DateTime fin = new DateTime(2017, 5, 8); while (debut = debut.AddDays(1) < lafin) { if (mois != debut.Month) { if (mois != 0) { Console.WriteLine("{0}-{1} : {2}", annee, mois, nbjours); } nbjours = 0; annee = debut.Year; mois = debut.Month; } nbjours++; } if (mois != 0) { Console.Write(string.Format("{0}-{1} : {2}", annee, mois, nbjours); }
Avec Linq et les expressions Lambda, .NET est en train de devenir une usine à gaz qui va finir par être pire que Java et PHP réunis : on peut écrire de la merde sans s'en rendre compte, en croyant même pourtant écrire quelque chose de plus propre (car plus court) qu'un code optimisé qui passe pour désuet.
On ne jouit bien que de ce qu’on partage.
J'ai utilisé une approche Linq à titre purement exploratoire, en précisant que c'était "dés-optimisé". Je comprends que tu n'approuves pas ce genre de code (et en réalité c'est une approche que je n'aurais moi-même pas cautionnée) mais je me suis permis cet "exercice de style" en sachant pertinemment que d'autres participants allaient ensuite proposer une solution crédible ; après-tout ce forum aussi un espace d'apprentissage et j'ai découvert pas mal de choses par la richesse des réponses qui étaient proposées, même celles qui n'étaient pas les plus pertinentes au cas concerné.
Je fait aussi ma proposition en C#.
La structure de François me plait bien, mais j'ai des exceptions lorsque je la met en application avec des dates différentes.
J’espère ne pas me faire crucifier par StringBuilder
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 static void Main(string[] args) { DateTime from = new DateTime(2017, 8, 24); DateTime to = new DateTime(2017, 12, 2); // Pour chaque mois de from jusqu'a to (1er jour du mois) for (DateTime currentMonth = new DateTime(from.Year, from.Month, 1); currentMonth <= new DateTime(to.Year, to.Month, 1); currentMonth = currentMonth.AddMonths(1)) { // Récupère le premier jour du mois en cours -1 DateTime start = currentMonth.AddDays(-1); // si from est supérieur au premier jour du mois en cours, on garde from if (from > start) start = from; // Récupère le dernier jour du mois en cours DateTime end = currentMonth.AddMonths(1).AddDays(-1); // si to est inférieur au dernier jour du mois en cours, on garde to if (to < end) end = to; // Affichage Console.WriteLine("{0} jours pour le mois {1} de l'année {2}", (end - start).Days, end.Month, end.Year); } }
Même si on dirait pas, aucune agressivité après ton code, ni à ton égard
Juste un petit coup de gueule après les expressions Lambda et Linq, qui autant sont très séduisants, autant, de mon point de vue, ne devrait être cantonnés qu'à des cas très précis : on ne maîtrise pas du tout les optimisations, et souvent le code qui en résulte est... juste abominable comparé à une solution "classique".
Pour moi c'est le même combat que les ORM : c'est joli, ça fait même le café, mais surtout ça fait tout ramer et encourage à développer sans réfléchir à la vélocité du programme.
Et pourtant, le concept de base de l'optimisation, c'est "pensez optimisé, pour ne pas avoir à optimiser ensuite, sinon il sera trop tard".
On ne jouit bien que de ce qu’on partage.
Effectivement ! Mea culpa. C'est ça de ne pas tester le code à fond...
Voici une version corrigée qui fonctionne mieux :
J'avoue que je n'ai lu qu'en diagonale le problème, sans voir que le premier jour devait être exclu. Après, pour l'inclusion/exclusion du début / fin de période, il suffit au pire d'ajouter ou retirer un jour sur les date de début et de fin. Bref, un simple ajustement...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 static void Main(string[] args) { DateTime from = new DateTime(2017, 2, 28); DateTime to = new DateTime(2018, 2, 28); for(int m = from.Year * 12 + (from.Month - 1); m <= to.Year * 12 + to.Month; m++) { DateTime d = new DateTime(m / 12, m % 12 + 1, 1); DateTime end = d.AddMonths(1).AddDays(-1) < to ? d.AddMonths(1).AddDays(-1) : to; DateTime start = d > from ? d : from; int nbJours = (end - start).Days + 1; Console.WriteLine("{0}/{1} : {2}", d.Month, d.Year, nbJours); } Console.ReadLine(); }
François DORIN
Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
Site internet | Profils Viadéo & LinkedIn
---------
Page de cours : fdorin.developpez.com
---------
N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels
D'accord ; j'avoue que sur le coup j'ai été un peu déconcerté par ton message et que je me suis senti un peu pris à partie, mais c'est bon, sans rancune Ayant débuté la programmation par du C et du C++ dans le fond je comprends tes remarques, bien qu'entre la première ligne de code que j'ai écrite et aujourd'hui mon point de vue sur le développement logiciel ait beaucoup évolué.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager