2009-02-26 15 views
118

Non riesco a pensare a una facile o due fodera che otterrebbe i mesi precedenti il ​​primo giorno e l'ultimo giorno.Visualizza le date del primo e dell'ultimo giorno del mese precedente C#

Sono LINQ-ficare una web app sondaggio, e hanno spremuto un nuovo requisito in.

L'indagine deve includere tutte le richieste di servizio per il mese precedente. Quindi, se è il 15 aprile, ho bisogno di tutti gli ID di richiesta delle Marche.

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

Non riesco a pensare facilmente alle date senza un interruttore. A meno che non sia cieco e trascuri un metodo interno per farlo.

risposta

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 linea se avete davvero bisogno di una o due linee.

+2

IIRC DateTime.Today è una chiamata piuttosto costosa, quindi è meglio memorizzare prima il valore in una variabile. Buona risposta comunque :) –

+1

Come funzionerà il 1 ° gennaio? –

+8

Funziona bene con Jan 1st, appena testato ... –

21

Il modo in cui ho fatto questo in passato è prima ottenere il primo giorno di questo mese

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

Quindi sottrarre al giorno per ottenere fine del mese scorso

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1); 

Quindi sottrarre un mese per ottenere primo giorno del mese precedente

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

net 2.0, Today.Days non funziona. –

+0

DateTime.Today.Day intendi –

+3

+1, ma per essere pedante, è meglio valutare DateTime.Today una volta e archiviare in una variabile locale. Se il codice inizia ad eseguire un nanosecondo prima di mezzanotte, due chiamate consecutive a DateTime.Today potrebbero restituire valori diversi. – Joe

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

DateTime.Today.Days -> 'System.DateTime' non contiene una definizione per 'Giorni' ... – andleer

+1

DateTime .Ora. Oggi intendi –

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

Cosa succede se DateTime.Now restituisce 2009-01-31 alla prima chiamata e 2009-02-01 alla seconda chiamata? –

+0

Questa sarà la fine di DateTime.Now :) modifica. Grazie. –

0

Se c'è qualche possibilità che i vostri datetimes non sono rigide date di calendario, si dovrebbe considerare l'utilizzo di confronti di esclusione DataFine ... questo caso non sarebbe possibile manca qualsiasi richiesta creati durante la data di 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 approccio che utilizzano metodi di estensione:

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); 
    } 
} 

Vedi questo link http://www.codeplex.com/fluentdatetime per alcune estensioni DateTime ispirate.

1

EDIT: Questo non è il modo di farlo!
Se today.Month - 1 = 0, come in gennaio, verrà generata un'eccezione. Questo è chiaramente il caso in cui essere furbi ti mette nei guai!

Un po 'più semplice del 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); 

salva un ulteriore creazione DateTime.

2

Il caso d'uso canonica in e-commerce è date di scadenza delle carte di credito, MM/aa. Sottrarre un secondo invece di un giorno. Altrimenti la carta apparirà scaduta per l'intero ultimo giorno del mese di scadenza.

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

Io uso questo semplice one-liner:

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

essere consapevoli, che mantiene il tempo.

+0

Proprio quello che volevo, espressione concisa che potrei usare all'interno di un ternario. Grazie! –

1

Questo è un introito sulla risposta di 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); 
} 

Si può chiamare in questo modo:

dateTimePickerFrom.Value = GetPreviousMonth(false); 
dateTimePickerTo.Value = GetPreviousMonth(true); 
Problemi correlati