ultimo primer obtener numero net mes dias año c# .net winforms datetime

c# - obtener - Obteniendo el primer y último día de un mes, usando un objeto DateTime determinado



ultimo dia del mes c# (11)

Quiero obtener el primer día y el último día del mes donde se encuentra una fecha determinada. La fecha proviene de un valor en un campo de IU.

Si estoy usando un selector de tiempo, podría decir

var maxDay = dtpAttendance.MaxDate.Day;

Pero estoy tratando de obtenerlo de un objeto DateTime. Entonces si tengo esto ...

DateTime dt = DateTime.today;

¿Cómo obtener el primer día y el último día del mes de dt ?


" Last day of month " es en realidad " First day of *next* month, minus 1 ". Así que esto es lo que uso, no es necesario el método "DaysInMonth":

public static DateTime FirstDayOfMonth(this DateTime value) { return new DateTime(value.Year, value.Month, 1); } public static DateTime LastDayOfMonth(this DateTime value) { return value.FirstDayOfMonth() .AddMonths(1) .AddMinutes(-1); }

NOTA: La razón por la que uso AddMinutes(-1) , no AddDays(-1) aquí es porque generalmente necesita estas funciones de fecha para informar de algún período de fecha, y cuando crea un informe por un período, la "fecha de finalización" en realidad debería ser algo así como el Oct 31 2015 23:59:59 para que su informe funcione correctamente, incluidos todos los datos del último día del mes.

Es decir, realmente obtienes el "último momento del mes" aquí. No es el último día.

OK, voy a callarme ahora.


Aquí puede agregar un mes para el primer día del mes actual que eliminar 1 día de ese día.

DateTime now = DateTime.Now; var startDate = new DateTime(now.Year, now.Month, 1); var endDate = startDate.AddMonths(1).AddDays(-1);


Este es un comentario más largo sobre las respuestas de @Sergey y @ Steffen. Después de haber escrito un código similar en el pasado, decidí comprobar qué era lo más destacado mientras recordaba que la claridad también es importante.

Resultado

Aquí hay un ejemplo de resultado de ejecución de prueba para 10 millones de iteraciones:

2257 ms for FirstDayOfMonth_AddMethod() 2406 ms for FirstDayOfMonth_NewMethod() 6342 ms for LastDayOfMonth_AddMethod() 4037 ms for LastDayOfMonth_AddMethodWithDaysInMonth() 4160 ms for LastDayOfMonth_NewMethod() 4212 ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod() 2491 ms for LastDayOfMonth_SpecialCase()

Código

Usé LINQPad 4 (en modo Programa C #) para ejecutar las pruebas con la optimización del compilador activada. Aquí está el código probado como métodos de extensión para mayor claridad y conveniencia:

public static class DateTimeDayOfMonthExtensions { public static DateTime FirstDayOfMonth_AddMethod(this DateTime value) { return value.Date.AddDays(1 - value.Day); } public static DateTime FirstDayOfMonth_NewMethod(this DateTime value) { return new DateTime(value.Year, value.Month, 1); } public static DateTime LastDayOfMonth_AddMethod(this DateTime value) { return value.FirstDayOfMonth_AddMethod().AddMonths(1).AddDays(-1); } public static DateTime LastDayOfMonth_AddMethodWithDaysInMonth(this DateTime value) { return value.Date.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - value.Day); } public static DateTime LastDayOfMonth_SpecialCase(this DateTime value) { return value.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - 1); } public static int DaysInMonth(this DateTime value) { return DateTime.DaysInMonth(value.Year, value.Month); } public static DateTime LastDayOfMonth_NewMethod(this DateTime value) { return new DateTime(value.Year, value.Month, DateTime.DaysInMonth(value.Year, value.Month)); } public static DateTime LastDayOfMonth_NewMethodWithReuseOfExtMethod(this DateTime value) { return new DateTime(value.Year, value.Month, value.DaysInMonth()); } } void Main() { Random rnd = new Random(); DateTime[] sampleData = new DateTime[10000000]; for(int i = 0; i < sampleData.Length; i++) { sampleData[i] = new DateTime(1970, 1, 1).AddDays(rnd.Next(0, 365 * 50)); } GC.Collect(); System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].FirstDayOfMonth_AddMethod(); } string.Format("{0} ms for FirstDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump(); GC.Collect(); sw.Restart(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].FirstDayOfMonth_NewMethod(); } string.Format("{0} ms for FirstDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump(); GC.Collect(); sw.Restart(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].LastDayOfMonth_AddMethod(); } string.Format("{0} ms for LastDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump(); GC.Collect(); sw.Restart(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].LastDayOfMonth_AddMethodWithDaysInMonth(); } string.Format("{0} ms for LastDayOfMonth_AddMethodWithDaysInMonth()", sw.ElapsedMilliseconds).Dump(); GC.Collect(); sw.Restart(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].LastDayOfMonth_NewMethod(); } string.Format("{0} ms for LastDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump(); GC.Collect(); sw.Restart(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].LastDayOfMonth_NewMethodWithReuseOfExtMethod(); } string.Format("{0} ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod()", sw.ElapsedMilliseconds).Dump(); for(int i = 0; i < sampleData.Length; i++) { sampleData[i] = sampleData[i].FirstDayOfMonth_AddMethod(); } GC.Collect(); sw.Restart(); for(int i = 0; i < sampleData.Length; i++) { DateTime test = sampleData[i].LastDayOfMonth_SpecialCase(); } string.Format("{0} ms for LastDayOfMonth_SpecialCase()", sw.ElapsedMilliseconds).Dump(); }

Análisis

Me sorprendieron algunos de estos resultados.

Aunque no hay mucho, FirstDayOfMonth_AddMethod fue ligeramente más rápido que FirstDayOfMonth_NewMethod en la mayoría de las ejecuciones de la prueba. Sin embargo, creo que este último tiene una intención un poco más clara y por eso tengo una preferencia por eso.

LastDayOfMonth_AddMethod fue un claro perdedor contra LastDayOfMonth_AddMethodWithDaysInMonth , LastDayOfMonth_NewMethod y LastDayOfMonth_NewMethodWithReuseOfExtMethod . Entre los tres más rápidos no hay mucho en él, por lo que se reduce a tus preferencias personales. Elijo la claridad de LastDayOfMonth_NewMethodWithReuseOfExtMethod con su reutilización de otro método de extensión útil. En mi humilde opinión, su intención es más clara y estoy dispuesto a aceptar el pequeño costo de rendimiento.

LastDayOfMonth_SpecialCase supone que está proporcionando el primero del mes en el caso especial en el que ya ha calculado esa fecha y utiliza el método add con DateTime.DaysInMonth para obtener el resultado. Esto es más rápido que las otras versiones, como era de esperar, pero a menos que tenga una necesidad desesperada de velocidad, no veo el sentido de tener este caso especial en su arsenal.

Conclusión

Aquí hay una clase de método de extensión con mis elecciones y, en general, estoy de acuerdo con @Steffen, creo:

public static class DateTimeDayOfMonthExtensions { public static DateTime FirstDayOfMonth(this DateTime value) { return new DateTime(value.Year, value.Month, 1); } public static int DaysInMonth(this DateTime value) { return DateTime.DaysInMonth(value.Year, value.Month); } public static DateTime LastDayOfMonth(this DateTime value) { return new DateTime(value.Year, value.Month, value.DaysInMonth()); } }

Si has llegado hasta aquí, ¡gracias por el tiempo! Ha sido divertido: ¬). Comente si tiene alguna otra sugerencia para estos algoritmos.


La respuesta aceptada aquí no tiene en cuenta el tipo de instancia de DateTime. Por ejemplo, si su instancia original de DateTime era de tipo UTC, al crear una nueva instancia de DateTime creará una instancia de tipo desconocido que se tratará como hora local en función de la configuración del servidor. Por lo tanto, la forma más adecuada de obtener la primera y la última fecha del mes sería esta:

var now = DateTime.UtcNow; var first = now.Date.AddDays(-(now.Date.Day - 1)); var last = first.AddMonths(1).AddTicks(-1);

De esta forma, se conserva la clase original Tipo de fecha y hora.


Obteniendo el rango de mes con .Net API (solo otra forma):

DateTime date = ... var firstDayOfMonth = new DateTime(date.Year, date.Month, 1); var lastDayOfMonth = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));


Para la cultura persa

PersianCalendar pc = new PersianCalendar(); var today = pc.GetDayOfMonth(DateTime.Now); var firstDayOfMonth = pc.GetDayOfMonth(DateTime.Now.AddDays(-(today-1))); var lastDayOfMonth = pc.GetDayOfMonth(DateTime.Now.AddMonths(1).AddDays(-today)); Console.WriteLine("First day "+ firstDayOfMonth); Console.WriteLine("Last day " + lastDayOfMonth);


Prueba este:

string strDate = DateTime.Now.ToString("MM/01/yyyy");


Si solo te importa la fecha

var firstDay = new DateTime(date.Year, date.Month, 1, 0, 0, 0, date.Kind); var lastDay = new DateTime(date.Year, date.Month, 1, 0, 0, 0, date.Kind).AddMonths(1).AddDays(-1);

Si quieres preservar el tiempo

var firstDay = new DateTime(date.Year, date.Month, 1, date.Hour, date.Minute, date.Second, date.Kind); var lastDay = new DateTime(date.Year, date.Month, 1, date.Hour, date.Minute, date.Second, date.Kind).AddMonths(1).AddDays(-1);


forma fácil de hacerlo

Begin = new DateTime(DateTime.Now.Year, DateTime.Now.Month,1).ToShortDateString(); End = new DataFim.Text = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)).ToShortDateString();


DateTime estructura DateTime almacena solo un valor, no un rango de valores. MinValue y MaxValue son campos estáticos, que mantienen el rango de valores posibles para las instancias de la estructura DateTime . Estos campos son estáticos y no se relacionan con una instancia particular de DateTime . Se relacionan con el tipo de DateTime sí mismo.

Lectura sugerida: estática (Referencia C #)

ACTUALIZACIÓN: Obteniendo rango mensual:

DateTime date = ... var firstDayOfMonth = new DateTime(date.Year, date.Month, 1); var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);


DateTime dCalcDate = DateTime.Now; dtpFromEffDate.Value = new DateTime(dCalcDate.Year, dCalcDate.Month, 1); dptToEffDate.Value = new DateTime(dCalcDate.Year, dCalcDate.Month, DateTime.DaysInMonth(dCalcDate.Year, dCalcDate.Month));