ASP.NET est un ensemble de technologies Web. C # est un langage. Vous devez vraiment penser à cela en termes de simple .NET. Maintenant, pour "mardi prochain" - est-ce "le premier mardi après aujourd'hui"? Si c'était lundi et que quelqu'un disait «à mardi prochain», je m'attendrais à ce que cela signifie 8 jours au lieu de 1. Et si aujourd'hui était un mardi? De quelle heure de la journée avez-vous besoin?
Jon Skeet le
Si aujourd'hui est mardi, vous voulez trouver la date du mardi prochain? Ou aujourd'hui c'est lundi, vous voulez trouver le 2ème mardi du lundi?
FIre Panda le
Le mardi le plus proche du jour où il se trouve.
brenjt le
2
@brenjtL: Et si c'est déjà mardi?
Jon Skeet le
Si déjà mardi, le même jour
brenjt
Réponses:
371
Comme je l'ai mentionné dans les commentaires, il y a différentes choses que vous pourriez vouloir dire par "mardi prochain", mais ce code vous donne "le mardi prochain à se produire, ou aujourd'hui si c'est déjà mardi":
DateTime today =DateTime.Today;// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysUntilTuesday =((int)DayOfWeek.Tuesday-(int) today.DayOfWeek+7)%7;DateTime nextTuesday = today.AddDays(daysUntilTuesday);
Si vous voulez donner "le temps d'une semaine" si c'est déjà mardi, vous pouvez utiliser:
// This finds the next Monday (or today if it's Monday) and then adds a day... so the// result is in the range [1-7]int daysUntilTuesday =(((int)DayOfWeek.Monday-(int) today.DayOfWeek+7)%7)+1;
... ou vous pouvez utiliser la formule originale, mais à partir de demain:
DateTime tomorrow =DateTime.Today.AddDays(1);// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysUntilTuesday =((int)DayOfWeek.Tuesday-(int) tomorrow.DayOfWeek+7)%7;DateTime nextTuesday = tomorrow.AddDays(daysUntilTuesday);
EDIT: Juste pour rendre ce joli et polyvalent:
publicstaticDateTimeGetNextWeekday(DateTime start,DayOfWeek day){// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysToAdd =((int) day -(int) start.DayOfWeek+7)%7;return start.AddDays(daysToAdd);}
Donc, pour obtenir la valeur "aujourd'hui ou dans les 6 prochains jours":
Wow, je me demandais simplement comment je pourrais avoir les nièmes jours jusqu'au mardi suivant et vous avez ensuite mis à jour votre réponse avec un exemple Nice. Merci
brenjt le
Il était difficile de choisir la bonne réponse. Mais le vôtre semble être le plus polyvalent et vous l'avez rendu facile à comprendre. Merci pour ton aide.
brenjt le
1
@brenjt: En fait, je dirais que Sven est plus polyvalent, car vous pouvez spécifier le jour de la semaine, mais c'est votre appel :) (j'ai maintenant édité le mien pour donner une version plus générale.)
Jon Skeet
1
La +7)%7solution est cependant assez sympa. Bien que la raison pour laquelle je ne l'ai pas utilisé soit parce que c'est un peu une micro-optimisation et qu'il est trop facile de se tromper (en plus de sacrifier une certaine lisibilité), à mon avis bien sûr.
Sven le
Un test unitaire: [TestMethod] public void ShouldGetNextSaturday () {var now = DateTime.Now; var test = GetNextWeekday (DateTime.Today, DayOfWeek.Saturday); Assert.IsTrue (now.Day <test.Day, "Le jour du mois prévu n'est pas ici."); Assert.IsTrue (test.DayOfWeek == DayOfWeek.Saturday, "Le jour de la semaine prévu n'est pas ici."); Assert.IsTrue ((test.Day - now.Day) <7, "L'intervalle de jour prévu n'est pas ici."); }
rasx
67
Cela devrait faire l'affaire:
staticDateTimeGetNextWeekday(DayOfWeek day){DateTime result =DateTime.Now.AddDays(1);while( result.DayOfWeek!= day )
result = result.AddDays(1);return result;}
Bonne réponse, si aujourd'hui c'est mardi (ce qui est ha) est-ce que cela reviendra aujourd'hui ou le mardi prochain?
brenjt le
3
Cela reviendra le mardi prochain. Si vous voulez qu'il revienne aujourd'hui, supprimez simplement le .AddDays(1)de la première ligne, de cette façon, il se vérifiera également DateTime.Now.
Sven le
7
Il existe des solutions moins verbeuses et plus intelligentes / élégantes à ce problème, mais la fonction C # suivante fonctionne très bien dans un certain nombre de situations.
/// <summary>/// Find the closest weekday to the given date/// </summary>/// <param name="includeStartDate">if the supplied date is on the specified day of the week, return that date or continue to the next date</param>/// <param name="searchForward">search forward or backward from the supplied date. if a null parameter is given, the closest weekday (ie in either direction) is returned</param>publicstaticDateTimeClosestWeekDay(thisDateTime date,DayOfWeek weekday,bool includeStartDate =true,bool? searchForward=true){if(!searchForward.HasValue&&!includeStartDate){thrownewArgumentException("if searching in both directions, start date must be a valid result");}var day = date.DayOfWeek;intadd=((int)weekday -(int)day);if(searchForward.HasValue){if(add<0&& searchForward.Value){add+=7;}elseif(add>0&&!searchForward.Value){add-=7;}elseif(add==0&&!includeStartDate){add= searchForward.Value?7:-7;}}elseif(add<-3){add+=7;}elseif(add>3){add-=7;}return date.AddDays(add);}
La seule réponse qui implémente comme extension de DateTime. Alors que les autres solutions fonctionnent toutes, l'avoir comme méthode d'extension produit le code le plus simple à utiliser.
Si aujourd'hui est lundi, la réponse que vous avez fournie rapporterait une semaine à partir de mardi, plutôt que demain.
Tony
5
@Jon Skeet bonne réponse.
Pour la journée précédente:
privateDateTimeGetPrevWeekday(DateTime start,DayOfWeek day){// The (... - 7) % 7 ensures we end up with a value in the range [0, 6]int daysToRemove =((int) day -(int) start.DayOfWeek-7)%7;return start.AddDays(daysToRemove);}
Notez que cette solution implique des nombres négatifs transmis à l'opérateur modulo. L' article de Wikipédia sur l'opérateur modulo dit que "Quand a ou n est négatif, la définition naïve s'effondre et les langages de programmation diffèrent dans la façon dont ces valeurs sont définies." Bien que cela fonctionne probablement en C #, une solution mathématiquement plus `` solide '' pour obtenir le même résultat serait d'échanger les DayOfWeekvaleurs comme ceci:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
Échantillon très simple pour inclure ou exclure la date actuelle, vous spécifiez la date et le jour de la semaine qui vous intéresse.
publicstaticclassDateTimeExtensions{/// <summary>/// Gets the next date./// </summary>/// <param name="date">The date to inspected.</param>/// <param name="dayOfWeek">The day of week you want to get.</param>/// <param name="exclDate">if set to <c>true</c> the current date will be excluded and include next occurrence.</param>/// <returns></returns>publicstaticDateTimeGetNextDate(thisDateTime date,DayOfWeek dayOfWeek,bool exclDate =true){//note: first we need to check if the date wants to move back by date - Today, + diff might move it forward or backwards to Today//eg: date - Today = 0 - 1 = -1, so have to move it forwardvar diff = dayOfWeek - date.DayOfWeek;var ddiff = date.Date.Subtract(DateTime.Today).Days+ diff;//note: ddiff < 0 : date calculates to past, so move forward, even if the date is really old, it will just move 7 days from date passed in//note: ddiff >= (exclDate ? 6 : 7) && diff < 0 : date is into the future, so calculated future weekday, based on dateif(ddiff <0|| ddiff >=(exclDate ?6:7)&& diff <0)
diff +=7;//note: now we can get safe values between 0 - 6, especially if past dates is being used
diff = diff %7;//note: if diff is 0 and we are excluding the date passed, we will add 7 days, eg: 1 week
diff += diff ==0& exclDate ?7:0;return date.AddDays(diff);}}
quelques cas de test
[TestMethod]publicvoidTestNextDate(){var date =newDateTime(2013,7,15);var start = date;//testing same month - forwardOnlyAssert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//16Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//17Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//18Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Friday));//19Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Saturday));//20Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Sunday));//21Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Monday));//22//testing same month - include dateAssert.AreEqual(start = date, date.GetNextDate(DayOfWeek.Monday,false));//15Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday,false));//16Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday,false));//17//testing month change - forwardOnly
date =newDateTime(2013,7,29);
start = date;Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//30Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//31Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//2013/09/01-month increasedAssert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Friday));//02//testing year change
date =newDateTime(2013,12,30);
start = date;Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//31Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//2014/01/01 - year increasedAssert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//02}
J'ai apporté des modifications supplémentaires à la réponse d'origine après quelques tests approfondis. Cela calculera désormais en toute sécurité le jour suivant en fonction de la date utilisée, passée, présente et future. Tous les exemples précédents étaient excellents, mais ont échoué dans certaines conditions. Je n'en ai pas fait une déclaration unique, de sorte que des commentaires supplémentaires puissent être faits sur ce que font les calculs. Le cas positif de Jon Skeet était excellent, même si le cas que j'avais était de reculer d'un jour d'une date, mais toujours plus grand qu'aujourd'hui, et que se passe-t-il s'il passe à aujourd'hui ou à hier ... cela l'a résolu.
AJB
1
Ça pourrait être une extension aussi, tout dépend
publicstaticclassDateTimeExtensions{publicstaticIEnumerable<DateTime>Next(thisDateTime date,DayOfWeek day){// This loop feels expensive and useless, but the point is IEnumerablewhile(true){if(date.DayOfWeek== day){yieldreturn date;}
date = date.AddDays(1);}}}
Usage
var today =DateTime.Today;foreach(var monday in today.Next(DayOfWeek.Monday)){Console.WriteLine(monday);Console.ReadKey();}
Réponses:
Comme je l'ai mentionné dans les commentaires, il y a différentes choses que vous pourriez vouloir dire par "mardi prochain", mais ce code vous donne "le mardi prochain à se produire, ou aujourd'hui si c'est déjà mardi":
Si vous voulez donner "le temps d'une semaine" si c'est déjà mardi, vous pouvez utiliser:
... ou vous pouvez utiliser la formule originale, mais à partir de demain:
EDIT: Juste pour rendre ce joli et polyvalent:
Donc, pour obtenir la valeur "aujourd'hui ou dans les 6 prochains jours":
Pour obtenir la valeur de "le mardi prochain sauf aujourd'hui":
la source
+7)%7
solution est cependant assez sympa. Bien que la raison pour laquelle je ne l'ai pas utilisé soit parce que c'est un peu une micro-optimisation et qu'il est trop facile de se tromper (en plus de sacrifier une certaine lisibilité), à mon avis bien sûr.Cela devrait faire l'affaire:
la source
.AddDays(1)
de la première ligne, de cette façon, il se vérifiera égalementDateTime.Now
.Il existe des solutions moins verbeuses et plus intelligentes / élégantes à ce problème, mais la fonction C # suivante fonctionne très bien dans un certain nombre de situations.
la source
la source
@Jon Skeet bonne réponse.
Pour la journée précédente:
Merci!!
la source
DayOfWeek
valeurs comme ceci:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
la source
Échantillon très simple pour inclure ou exclure la date actuelle, vous spécifiez la date et le jour de la semaine qui vous intéresse.
quelques cas de test
la source
Ça pourrait être une extension aussi, tout dépend
Usage
la source
Maintenant dans la saveur oneliner - au cas où vous auriez besoin de le passer comme paramètre dans un mécanisme.
Dans ce cas précis:
la source
Version Objectif C:
la source