O ASP.NET é um conjunto de tecnologias da web. C # é uma linguagem. Você realmente precisa pensar nisso em termos de .NET simples. Agora, para "próxima terça-feira" - essa é "a primeira terça-feira depois de hoje"? Se fosse segunda-feira e alguém dissesse "até a próxima terça-feira", eu esperaria que isso significasse 8 dias em vez de 1. E se hoje for terça-feira? Que hora do dia você precisa?
precisa
Se hoje é terça-feira, você quer encontrar a data em que será a próxima terça-feira? Ou hoje é segunda-feira, você quer encontrar a segunda terça-feira a partir de segunda-feira?
Página
A terça-feira mais próxima daqui para frente, em que dia é sempre.
18711 br11-
2
@brenjtL: E se já é terça-feira?
precisa
Se já terça-feira, em seguida, no mesmo dia
brenjt
Respostas:
371
Como mencionei nos comentários, há várias coisas que você poderia dizer com "próxima terça-feira", mas esse código fornece "a próxima terça-feira a ocorrer, ou hoje, se já é terça-feira":
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);
Se você deseja dar "uma semana", se já é terça-feira, pode usar:
// 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 você pode usar a fórmula original, mas a partir de amanhã:
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: Apenas para tornar isso agradável e versátil:
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);}
Portanto, para obter o valor de "hoje ou nos próximos 6 dias":
Uau, eu estava pensando em como eu poderia passar o nono dia até a próxima terça-feira e você atualizou sua resposta com um exemplo Agradável. Graças
brenjt
Foi difícil escolher a resposta correta. Mas o seu parece ser o mais versátil e você facilitou o entendimento. Obrigado pela ajuda.
brenjt
1
@brenjt: Na verdade, eu diria que o Sven's é mais versátil, como você pode especificar o dia da semana, mas a decisão é sua :) (agora editei o meu para fornecer uma versão mais generalizada.)
Jon Skeet
1
A +7)%7solução é bastante agradável. Embora a razão pela qual eu não usei isso seja porque é um pouco de micro-otimização e muito fácil de errar (além de sacrificar alguma legibilidade), imho, é claro.
Sven
Um teste de unidade: [TestMethod] public void ShouldGetNextSaturday () {var now = DateTime.Now; var test = GetNextWeekday (DateTime.Today, DayOfWeek.Saturday); Assert.IsTrue (now.Day <test.Day, "O dia do mês esperado não está aqui."); Assert.IsTrue (test.DayOfWeek == DayOfWeek.Saturday, "O dia da semana esperado não está aqui."); Assert.IsTrue ((test.Day - now.Day) <7, "O intervalo esperado do dia não está aqui."); }
rasx
67
Isso deve fazer o truque:
staticDateTimeGetNextWeekday(DayOfWeek day){DateTime result =DateTime.Now.AddDays(1);while( result.DayOfWeek!= day )
result = result.AddDays(1);return result;}
Ótima resposta, se hoje é terça-feira (que é ha) isso voltará hoje ou na próxima terça-feira?
brenjt
3
Isso retornará na próxima terça-feira. Se você deseja que ele retorne hoje, basta remover o .AddDays(1)da primeira linha, para que ele também se verifique DateTime.Now.
Sven
7
Existem soluções menos detalhadas e mais inteligentes / elegantes para esse problema, mas a função C # a seguir funciona muito bem em várias situações.
/// <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);}
A única resposta que implementa como extensão ao DateTime. Enquanto as outras soluções funcionam, tê-lo como método de extensão produz o código mais fácil de usar.
Se hoje for segunda-feira, a resposta que você forneceu renderia uma semana a partir de terça-feira, e não amanhã.
Tony
5
@ Jon Skeet boa resposta.
Para o dia anterior:
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);}
Observe que esta solução envolve números negativos entregues ao operador do módulo. O artigo da Wikipedia sobre o operador modulo diz que "Quando a ou n é negativo, a definição ingênua se decompõe e as linguagens de programação diferem na forma como esses valores são definidos". Enquanto isso provavelmente funciona em C #, uma solução matematicamente mais 'sólido' para obter o mesmo resultado seria para trocar os DayOfWeekvalores da seguinte forma:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
Amostra muito simples para incluir ou excluir a data atual, você especifica a data e o dia da semana em que está interessado.
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);}}
alguns casos de teste
[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}
Fiz alterações adicionais da resposta original após alguns testes extensivos. Agora, ele calculará com segurança o dia seguinte com base na data usada, passada, presente e futura. Todos os exemplos anteriores foram ótimos, mas falharam sob certas condições. Não fiz uma declaração de uma linha, para que comentários adicionais pudessem ser feitos sobre o que os cálculos estão fazendo. O caso positivo de Jon Skeet foi ótimo, embora o caso que eu tive foi afastar um dia de uma data, mas ainda maior que Hoje, e se ele se mudar para hoje ou ontem ... isso resolveu.
AJB
1
Ela poderia ser uma extensão também, tudo depende
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);}}}
Uso
var today =DateTime.Today;foreach(var monday in today.Next(DayOfWeek.Monday)){Console.WriteLine(monday);Console.ReadKey();}
Respostas:
Como mencionei nos comentários, há várias coisas que você poderia dizer com "próxima terça-feira", mas esse código fornece "a próxima terça-feira a ocorrer, ou hoje, se já é terça-feira":
Se você deseja dar "uma semana", se já é terça-feira, pode usar:
... ou você pode usar a fórmula original, mas a partir de amanhã:
EDIT: Apenas para tornar isso agradável e versátil:
Portanto, para obter o valor de "hoje ou nos próximos 6 dias":
Para obter o valor para "na próxima terça-feira, exceto hoje":
fonte
+7)%7
solução é bastante agradável. Embora a razão pela qual eu não usei isso seja porque é um pouco de micro-otimização e muito fácil de errar (além de sacrificar alguma legibilidade), imho, é claro.Isso deve fazer o truque:
fonte
.AddDays(1)
da primeira linha, para que ele também se verifiqueDateTime.Now
.Existem soluções menos detalhadas e mais inteligentes / elegantes para esse problema, mas a função C # a seguir funciona muito bem em várias situações.
fonte
fonte
@ Jon Skeet boa resposta.
Para o dia anterior:
Obrigado!!
fonte
DayOfWeek
valores da seguinte forma:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
fonte
Amostra muito simples para incluir ou excluir a data atual, você especifica a data e o dia da semana em que está interessado.
alguns casos de teste
fonte
Ela poderia ser uma extensão também, tudo depende
Uso
fonte
Agora com sabor oneliner - caso você precise passá-lo como parâmetro para algum mecanismo.
Nesse caso específico:
fonte
Versão do objetivo C:
fonte