Esiste una funzione C# che mi darà l'ultimo giorno del Trimestre più recente data una data?Quartiere completato più vicino
Per esempio,
var lastDayOfLastQuarter = SomeFunction(jan 3, 2010);
avrebbe fissato lastDayOfLastQuarter = 31 dic 2009
Esiste una funzione C# che mi darà l'ultimo giorno del Trimestre più recente data una data?Quartiere completato più vicino
Per esempio,
var lastDayOfLastQuarter = SomeFunction(jan 3, 2010);
avrebbe fissato lastDayOfLastQuarter = 31 dic 2009
public static DateTime NearestQuarterEnd(this DateTime date) {
IEnumerable<DateTime> candidates =
QuartersInYear(date.Year).Union(QuartersInYear(date.Year - 1));
return candidates.Where(d => d < date.Date).OrderBy(d => d).Last();
}
static IEnumerable<DateTime> QuartersInYear(int year) {
return new List<DateTime>() {
new DateTime(year, 3, 31),
new DateTime(year, 6, 30),
new DateTime(year, 9, 30),
new DateTime(year, 12, 31),
};
}
Usage:
DateTime date = new DateTime(2010, 1, 3);
DateTime quarterEnd = date.NearestQuarterEnd();
Questo metodo ha il vantaggio nel senso che se si dispone di una definizione di dispari di quarti (ad esempio, l'anno fiscale è diverso rispetto all'anno solare), il metodo QuartersInYear
è facilmente modificato per gestire questo.
+1 - Semplice, estensibile, facile da verificare e comprendere. Lo adoro. – LBushkin
Oh, mi piacerebbe sapere perché questo è stato appena downvoted. – jason
Attenzione che questo metodo supporrà che il trimestre sia terminato quando si passa l'ultimo giorno, ovvero, il nuovo DateTime (2012, 9, 30) restituirà "2012-09-30", anche se si potrebbe obiettare che nell'ultima data , il trimestre non è ancora finito. Inoltre, il nome del metodo è leggermente fuorviante, poiché restituirà l'ultimo trimestre, non il più vicino se questo è in futuro. –
Prova questo:
I AddMonths(-(d.Month-1) % 3))
mosse DATEVALUE al giorno equivilent del primo mese del trimestre, e poi lo AddDays (-day)
si sposta indietro fino all'ultimo giorno del mese precedente.
DateTime d = Datetime.Now;
DateTime lastDayOfLastQuarter = d.AddMonths(-((d.Month-1)%3)).AddDays(-d.Day);
Ciò non riesce, ad esempio, per "Giorno = 1", "Mese = 12", "Anno = 2009". – jason
perché la proprietà del mese è 1-12, (non 0-11 come pensavo), corretta ora –
Ok, penso che funzioni. Rimuovi downvot. Tuttavia, lo svantaggio di questo metodo è che dipende in larga misura dai trimestri definiti come gli ultimi giorni del terzo, sesto, nono e dodicesimo mese dell'anno. Se si utilizza una definizione diversa, questo metodo non è facilmente adattabile (le aziende trasferiscono le proprie date di rendicontazione finanziaria più spesso di quanto si possa pensare). – jason
Assumendo quarti finiscono sempre ad intervalli di 3 mesi che si potrebbe fare:
Forse non la soluzione migliore, ma molto facile da leggere e modificare rispetto ad altre soluzioni offerte.
public DateTime LastDayOfLastQuarter(DateTime date)
{
int result = (int)(date.Month/3)
switch (result)
{
// January - March
case 0:
return new DateTime(date.Year - 1, 12, 31);
// April - June
case 1:
return new DateTime(date.Year, 3, 31);
// July - September
case 2:
return new DateTime(date.Year, 6, 30);
// October - December
case 3:
return new DateTime(date.Year, 9, 30);
}
}
Molti errori in questo codice: 1. mancanza di punti e virgola in ciascuna istruzione; 2. tipo di reso dovrebbe essere DateTime i.s.o. vuoto; 3. Manca un caso predefinito, con le impostazioni predefinite del compilatore, si otterrà "non tutti i percorsi di codice restituiscono un valore". –
@ R.Schreurs, corretto tutto tranne l'avviso del compilatore per ya. Cosa suggeriresti esattamente per un ritorno che non dovrebbe mai essere eseguito logicamente? –
In questo caso avrei generato un'eccezione: default: lanciare una nuova ApplicationException (string.Format ("{0} non è un numero valido per un quarto.", Risultato)); Il compilatore sarà felice e il tuo codice è chiaro su ciò che accetta come valido. Manca ancora 1 punto e virgola ... solo per curiosità, perché non scrivi il tuo codice in VS.Net e lo compili solo prima di postarlo qui? Chiunque cerchi questa funzione sarebbe felice se potesse essere semplicemente copiato e incollato e non necessiti di debugging. –
Ecco una semplice funzione per darvi l'ultimo giorno del trimestre in corso (supponendo che si sta utilizzando un calendario standard).
DateTime LastDayOfQuarter(DateTime today)
{
int quarter = (today.Month-1)/3;
int lastMonthInQuarter = (quarter +1) * 3;
int lastDayInMonth = DateTime.DaysInMonth(today.Year, lastMonthInQuarter);
return new DateTime(today.Year, lastMonthInQuarter, lastDayInMonth);
}
Spero che questo aiuti.
Una funzione semplice in grado di calcolare gli ultimi giorni del mese più recentemente completato:
public static DateTime LastQuarter(DateTime date)
{
return new DateTime(date.Year, date.Month - ((date.Month - 1) % 3), 1).AddDays(-1);
}
è possibile utilizzare una semplice istruzione switch per controllare che il quartiere dei dati cascate di data e restituire l'ultimo giorno del trimestre.
Func<int, int> q = (i) => { return ((i - 1)/3) + 1; };
prova:
Enumerable.Range(1, 12).Select(i => q(i));
Avresti bisogno di essere in grado di definire quando i quarti di inizio e fine. – Paddy
Oh, quello è probabilmente solo un caso speciale del metodo 'DoMagic()' che risolve miracolosamente quello che vuoi in qualsiasi contesto :-). Seriamente, non esiste un metodo simile nella libreria di classi base, ma puoi sicuramente scriverne uno tuo. – Joey
Quarti standard –