2009-02-26 187 views
118

No puedo pensar en uno o dos delineadores fáciles que recibirían los meses anteriores el primer día y el último día.Obtenga las fechas del primer y último día del mes anterior en C#

Soy LINQ ifying una aplicación web encuesta, y se apretó un nuevo requisito.

La encuesta debe incluir todas las solicitudes de servicio para el mes anterior. Entonces, si es el 15 de abril, necesito todos los ID de solicitud de Marche.

var RequestIds = (from r in rdc.request 
        where r.dteCreated >= LastMonthsFirstDate && 
        r.dteCreated <= LastMonthsLastDate 
        select r.intRequestId); 

No puedo pensar en las fechas fácilmente sin un interruptor. A menos que sea ciego y pase por alto un método interno para hacerlo.

Respuesta

254
var today = DateTime.Today; 
var month = new DateTime(today.Year, today.Month, 1);  
var first = month.AddMonths(-1); 
var last = month.AddDays(-1); 

In-line si realmente necesita una o dos líneas.

+2

IIRC DateTime. Hoy en día es una llamada bastante costosa, por lo que es mejor que primero almacenes el valor en una variable. Buena respuesta de todos modos :) –

+1

¿Cómo funciona esto el 1 de enero? –

+8

Funciona bien con el 1 de enero, acaba de probar ... –

21

La forma en que he hecho esto en el pasado se adquiere por primera vez el primer día de este mes

dFirstDayOfThisMonth = DateTime.Today.AddDays(- (DateTime.Today.Day - 1)); 

Luego restar un día para conseguir fines del mes pasado

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1); 

Luego reste una meses para conseguir el primer día del mes anterior

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1); 
+0

red 2.0, Today.Days no está funcionando. –

+0

DateTime.Today.Day te refieres a –

+3

+1, pero para ser pedante, es mejor evaluar DateTime.Today una vez y almacenar en una variable local. Si su código comienza a ejecutarse un nanosegundo antes de la medianoche, dos llamadas consecutivas a DateTime.Today podrían devolver valores diferentes. – Joe

8
DateTime LastMonthLastDate = DateTime.Today.AddDays(0 - DateTime.Today.Day); 
DateTime LastMonthFirstDate = LastMonthLastDate.AddDays(1 - LastMonthLastDate.Day); 
+0

DateTime.Today.Days -> 'System.DateTime' no contiene una definición para 'Days' ... – andleer

+1

DateTime .Hoy en día, dices –

1
DateTime now = DateTime.Now; 
int prevMonth = now.AddMonths(-1).Month; 
int year = now.AddMonths(-1).Year; 
int daysInPrevMonth = DateTime.DaysInMonth(year, prevMonth); 
DateTime firstDayPrevMonth = new DateTime(year, prevMonth, 1); 
DateTime lastDayPrevMonth = new DateTime(year, prevMonth, daysInPrevMonth); 
Console.WriteLine("{0} {1}", firstDayPrevMonth.ToShortDateString(), 
    lastDayPrevMonth.ToShortDateString()); 
+1

¿Qué sucede si DateTime.Now cede el 2009-01-31 en la primera llamada y 2009-02-01 en la segunda llamada? –

+0

Esa será la finalización de la edición DateTime.Now :). Gracias. –

0

Si hay alguna posibilidad de que sus datetimes no son estrictas fechas del calendario, usted debe considerar el uso de comparaciones de exclusión EndDate ... Esto le permitirá no todas las solicitudes creadas durante la fecha de Jan 31.

DateTime now = DateTime.Now; 
DateTime thisMonth = new DateTime(now.Year, now.Month, 1); 
DateTime lastMonth = thisMonth.AddMonths(-1); 

var RequestIds = rdc.request 
    .Where(r => lastMonth <= r.dteCreated) 
    .Where(r => r.dteCreated < thisMonth) 
    .Select(r => r.intRequestId); 
4

Un enfoque utilizando métodos de extensión:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DateTime t = DateTime.Now; 

     DateTime p = t.PreviousMonthFirstDay(); 
     Console.WriteLine(p.ToShortDateString()); 

     p = t.PreviousMonthLastDay(); 
     Console.WriteLine(p.ToShortDateString()); 


     Console.ReadKey(); 
    } 
} 


public static class Helpers 
{ 
    public static DateTime PreviousMonthFirstDay(this DateTime currentDate) 
    { 
     DateTime d = currentDate.PreviousMonthLastDay(); 

     return new DateTime(d.Year, d.Month, 1); 
    } 

    public static DateTime PreviousMonthLastDay(this DateTime currentDate) 
    { 
     return new DateTime(currentDate.Year, currentDate.Month, 1).AddDays(-1); 
    } 
} 

ver este enlace http://www.codeplex.com/fluentdatetime para algunas inspiradas extensiones DateTime.

1

EDITAR: ¡Esta no es la manera de hacerlo!
Si hoy.Mes - 1 = 0, como en enero, arrojará una excepción. ¡Este es claramente un caso donde ser inteligente te mete en problemas!

Un poco más sencillo que el accepted answer:

var today = DateTime.Today 
var first = new DateTime(today.Year, today.Month - 1, 1); 
var last = new DateTime(today.Year, today.Month, 1).AddDays(-1); 

países una creación adicional DateTime.

2

El caso de uso canónico en el comercio electrónico es fechas de caducidad de tarjetas de crédito, MM/yy. Resta un segundo en lugar de un día. De lo contrario, la tarjeta aparecerá expirada durante todo el último día del mes de vencimiento.

DateTime expiration = DateTime.Parse("07/2013"); 
DateTime endOfTheMonthExpiration = new DateTime(
    expiration.Year, expiration.Month, 1).AddMonths(1).AddSeconds(-1); 
3

utilizo este sencillo de una sola línea:

public static DateTime GetLastDayOfPreviousMonth(this DateTime date) 
{ 
    return date.AddDays(-date.Day); 
} 

Tenga en cuenta, que retiene el tiempo.

+0

Justo lo que quería, expresión concisa que podría usar dentro de un ternario. ¡Gracias! –

1

Esta es una toma en la respuesta de Mike W:

internal static DateTime GetPreviousMonth(bool returnLastDayOfMonth) 
{ 
    DateTime firstDayOfThisMonth = DateTime.Today.AddDays(- (DateTime.Today.Day - 1)); 
    DateTime lastDayOfLastMonth = firstDayOfThisMonth.AddDays (-1); 
    if (returnLastDayOfMonth) return lastDayOfLastMonth; 
    return firstDayOfThisMonth.AddMonths(-1); 
} 

Se le puede llamar así:

dateTimePickerFrom.Value = GetPreviousMonth(false); 
dateTimePickerTo.Value = GetPreviousMonth(true); 
Cuestiones relacionadas