2009-12-22 47 views
11

是否有一個C#函數會給我最近完成的季度的最後一天給定日期?最近完成季度

例如,

var lastDayOfLastQuarter = SomeFunction(jan 3, 2010); 

將設置lastDayOfLastQuarter = 2009年12月31日

+0

你需要能夠當你的季開始和結束界定。 – Paddy 2009-12-22 15:46:48

+2

哦,那可能只是'DoMagic()'方法的一個特例,它可以在任何情況下奇蹟般地解決你想要的問題:-)。說真的,在基類庫中沒有這樣的方法,但是你一定可以編寫你自己的。 – Joey 2009-12-22 15:48:00

+0

標準宿舍 – 2009-12-22 15:48:12

回答

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

用法:

DateTime date = new DateTime(2010, 1, 3); 
DateTime quarterEnd = date.NearestQuarterEnd(); 

這種方法的優點是,如果你有四分之三的一個奇怪的定義(例如,財年比歷年不同)的方法QuartersInYear是很容易修改來處理這個。

+2

+1 - 簡單,可擴展,易於驗證和理解。愛它。 – LBushkin 2009-12-22 16:08:11

+1

哦,我想知道爲什麼這只是downvoted。 – jason 2011-06-27 14:44:44

+1

請注意,如果您在最後一天通過該方法,則此方法將假定該季度已結束,也就是說,新的DateTime(2012,9,30)將返回「2012-09-30」,但有人可能會說在最後一天,該季度還沒有結束。 此外,該方法的名稱有些誤導,因爲它會返回最新的季度,而不是最近的,如果這是將來。 – 2012-09-14 16:09:12

2

試試這個:
AddMonths(-(d.Month-1) % 3))移動DATEVALUE到正月equivilent日在本季度,然後AddDays (-day)移回到前一個月的最後一天。

DateTime d = Datetime.Now; 
    DateTime lastDayOfLastQuarter = d.AddMonths(-((d.Month-1)%3)).AddDays(-d.Day); 
+0

例如,「日= 1」,「月= 12」,「年= 2009」等情況均失敗。 – jason 2009-12-22 15:59:39

+0

,因爲月屬性是1-12,(不是0-11,因爲我認爲),現在更正 – 2009-12-22 16:01:55

+0

好吧,我認爲這是有效的。 Downvote刪除。然而,這種方法的缺點是嚴重依賴宿舍被定義爲今年第三,第六,第九和第十二個月的最後幾天。如果使用不同的定義,則此方法不易適用於此(公司更頻繁地移動其財務報表報表日期)。 – jason 2009-12-22 16:06:19

2

假設宿舍總是最後3周月的時間,你可以這樣做:

也許不是最好的解決辦法,但很容易讀取和修改相比提供其他解決方案。

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

此代碼中的許多錯誤: 1.每條語句上缺少分號; 2.返回類型應該是DateTime i.s.o.無效; 3.缺少默認情況下,使用默認編譯器設置,您會得到「並非所有代碼路徑都返回值」。 – 2012-09-14 15:38:20

+0

@ R.Schreurs,修復了除ya之外的所有編譯器警告。對於從邏輯上不應執行的回報,你會提出什麼建議? – 2012-09-14 15:50:39

+1

我會在這種情況下拋出異常: 默認值: 拋出新的ApplicationException(string.Format(「{0}不是一個季度的有效數字。」,result)); 編譯器會很高興,你的代碼清楚它接受的是有效的。 仍然缺少1分號......出於好奇,爲什麼不在VS.Net中編寫代碼,並在發佈之前編譯它? 任何尋找這個功能的人都會很高興,如果它可以被複制和粘貼,而不需要調試。 – 2012-09-17 20:38:08

1

下面是一個簡單的函數,爲您提供當前季度的最後一天(假設您使用的是標準日曆)。

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

希望有幫助。

2

一個簡單的函數可以計算最近完成的月的最後幾天:

public static DateTime LastQuarter(DateTime date) 
{ 
    return new DateTime(date.Year, date.Month - ((date.Month - 1) % 3), 1).AddDays(-1); 
} 
0

您可以使用一個簡單的開關語句來檢查哪一個季度給定日期瀑布,並返回該季度的最後一天。

1
Func<int, int> q = (i) => { return ((i - 1)/3) + 1; }; 

測試:

Enumerable.Range(1, 12).Select(i => q(i));