ASP.NET es un conjunto de tecnologías web. C # es un lenguaje. Realmente necesita pensar en esto en términos de .NET. Ahora, para "el próximo martes", ¿es "el primer martes después de hoy"? Si fuera lunes y alguien dijera "nos vemos el próximo martes", esperaría que eso signifique 8 días en lugar de 1. ¿Qué tal si hoy es martes? ¿A qué hora del día necesitas?
Jon Skeet
Si hoy es martes, ¿quieres saber la fecha en que será el próximo martes? O hoy es lunes, ¿quieres encontrar el segundo martes del lunes?
Fuego Panda
El martes más cercano se adelanta a cualquier día en particular.
brenjt
2
@brenjtL: ¿Y si ya es martes?
Jon Skeet
Si ya es martes, ese mismo día
brenjt
Respuestas:
371
Como mencioné en los comentarios, hay varias cosas a las que se podría referir con "el próximo martes", pero este código le da "el próximo martes que ocurrirá, o hoy si ya es martes":
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 desea dar "una semana" si ya es martes, puede 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;
... o podrías usar la fórmula original, pero a partir de mañana:
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);
EDITAR: Solo para hacer esto agradable y 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);}
Entonces, para obtener el valor de "hoy o en los próximos 6 días":
Wow, me preguntaba cómo podría llegar enésimo día hasta el próximo martes y luego actualizaste tu respuesta con un ejemplo Nice. Gracias
brenjt
Fue difícil elegir la respuesta correcta. Pero el tuyo parece ser el más versátil y lo hiciste fácil de entender. Gracias por tu ayuda.
brenjt
1
@brenjt: De hecho, diría que Sven's es más versátil, ya que puedes especificar el día de la semana, pero es tu decisión :) (Ahora he editado el mío para dar una versión más generalizada)
Jon Skeet
1
Sin +7)%7embargo, la solución es bastante buena. Aunque la razón por la que no utilicé eso es porque es un poco una microoptimización y es demasiado fácil equivocarse (además de sacrificar algo de legibilidad), en mi opinión, por supuesto.
Sven
Una prueba unitaria: [TestMethod] public void ShouldGetNextSaturday () {var now = DateTime.Now; prueba var = GetNextWeekday (DateTime.Today, DayOfWeek.Saturday); Assert.IsTrue (now.Day <test.Day, "El mes esperado no está aquí"); Assert.IsTrue (test.DayOfWeek == DayOfWeek.Saturday, "El día de la semana esperado no está aquí"); Assert.IsTrue ((test.Day - now.Day) <7, "El intervalo de días esperado no está aquí"); }
rasx
67
Esto debería funcionar:
staticDateTimeGetNextWeekday(DayOfWeek day){DateTime result =DateTime.Now.AddDays(1);while( result.DayOfWeek!= day )
result = result.AddDays(1);return result;}
Gran respuesta, si hoy es martes (que es ja) ¿volverá esto hoy o el próximo martes?
brenjt
3
Esto volverá el próximo martes. Si desea que regrese hoy, simplemente elimine el .AddDays(1)de la primera línea, de esa manera también se comprobará DateTime.Now.
Sven
7
Hay soluciones menos detalladas y más inteligentes / elegantes para este problema, pero la siguiente función de C # funciona realmente bien para una serie de situaciones.
/// <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 única respuesta que se implementa como extensión de DateTime. Si bien las otras soluciones funcionan, tenerlo como método de extensión produce el código más fácil de usar.
Si hoy es lunes, la respuesta que proporcionó produciría una semana a partir del martes, en lugar de mañana.
Tony
5
@ Jon Skeet buena respuesta.
Para el día 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);}
Tenga en cuenta que esta solución implica números negativos entregados al operador del módulo. El artículo de Wikipedia sobre el operador de módulo dice que "cuando a o n es negativo, la definición ingenua se descompone y los lenguajes de programación difieren en cómo se definen estos valores". Si bien esto probablemente funcione en C #, una solución matemáticamente más 'sólida' para obtener el mismo resultado sería intercambiar los DayOfWeekvalores de esta manera:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
Muestra muy simple para incluir o excluir la fecha actual, usted especifica la fecha y el día de la semana que le interesa.
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);}}
algunos casos de prueba
[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}
He realizado cambios adicionales de la respuesta original después de algunas pruebas exhaustivas. Esto ahora calculará de forma segura el día siguiente en función de la fecha de uso, pasado, presente y futuro. Todos los ejemplos anteriores fueron geniales, pero fallaron bajo ciertas condiciones. No hice una declaración de una sola línea, para que pudieran hacerse comentarios adicionales sobre lo que están haciendo los cálculos. El caso positivo de Jon Skeet fue genial, aunque el caso que tuve fue retroceder 1 día desde una fecha, pero aún mayor que Hoy, y qué pasa si se mueve hoy o ayer ... esto lo resolvió.
AJB
1
También podría ser una extensión, todo 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();}
Respuestas:
Como mencioné en los comentarios, hay varias cosas a las que se podría referir con "el próximo martes", pero este código le da "el próximo martes que ocurrirá, o hoy si ya es martes":
Si desea dar "una semana" si ya es martes, puede usar:
... o podrías usar la fórmula original, pero a partir de mañana:
EDITAR: Solo para hacer esto agradable y versátil:
Entonces, para obtener el valor de "hoy o en los próximos 6 días":
Para obtener el valor para "el próximo martes excluyendo hoy":
fuente
+7)%7
embargo, la solución es bastante buena. Aunque la razón por la que no utilicé eso es porque es un poco una microoptimización y es demasiado fácil equivocarse (además de sacrificar algo de legibilidad), en mi opinión, por supuesto.Esto debería funcionar:
fuente
.AddDays(1)
de la primera línea, de esa manera también se comprobaráDateTime.Now
.Hay soluciones menos detalladas y más inteligentes / elegantes para este problema, pero la siguiente función de C # funciona realmente bien para una serie de situaciones.
fuente
fuente
@ Jon Skeet buena respuesta.
Para el día anterior:
¡¡Gracias!!
fuente
DayOfWeek
valores de esta manera:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
fuente
Muestra muy simple para incluir o excluir la fecha actual, usted especifica la fecha y el día de la semana que le interesa.
algunos casos de prueba
fuente
También podría ser una extensión, todo depende
Uso
fuente
Ahora en sabor de línea de papel, en caso de que necesite pasarlo como parámetro a algún mecanismo.
En este caso específico:
fuente
Versión del objetivo C:
fuente