tags:

views:

453

answers:

5

Is there a C# function which will give me the last day of the most recently finished Quarter given a date?

For example,

  var lastDayOfLastQuarter = SomeFunction(jan 3, 2010);

would set lastDayOfLastQuarter = Dec 31, 2009

A: 

Try this:
The AddMonths(-(d.Month-1) % 3)) moves the datevalue to the equivilent day of the first month in the quarter, and then the AddDays (-day) moves back to the last day of the preceding month.

  DateTime d = Datetime.Now;
  DateTime lastDayOfLastQuarter = d.AddMonths(-((d.Month-1)%3)).AddDays(-d.Day);
Charles Bretana
This fails for, say, `Day = 1`, `Month = 12`, `Year = 2009`.
Jason
because month property is 1-12, (not 0-11 as I thought), corrected now
Charles Bretana
Okay, I think that works. Downvote removed. However, the disadvantage of this method is that is heavily dependent on quarters being defined as the last days of the third, sixth, ninth and twelfth months of the year. If a different definition is used this method is not easily adaptable to that (companies move their financial statement reporting dates more often than you might think).
Jason
This is first I've EVER heard of "redefining quarters differently than standard calendar quarter 1-3, 4-6, 7-9, 10-12. But I just did some research and saw that for estimated taxes some C-Corps ar allowed to use 1-3, 4-5, 6-8, and 9-12... very interesting...
Charles Bretana
But if this odd pattern is in use, then any function to dop what OP asked would have to be passed info on how quarters were redefined... A different problem entirely from what OP asked. (He specofies standard quarters)
Charles Bretana
I think Cisco is an example of a company with their quarters ending in the first, fourth, seventh and tenth months of the years.
Jason
they're probably aligned with FY, at least they're still all three months long.. The examples I found are 2 and 4 months long "quarters" to adjust for varying expected revenue streams during the year, to adjust I assume to keep the "monetary revenue" size of the quarters balaanced...
Charles Bretana
Yes, that will happen for companies with seasonal cash flows.
Jason
+7  A: 
public static DateTime NearestQuarterEnd(this DateTime date) {
    IEnumerable<DateTime> candidates = 
        QuartersInYear(date.Year).Union(QuartersInYear(date.Year - 1));
    return candidates.Where(d => d <= 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();

This method has the advantage in that if you have an odd definition of quarters (for example, fiscal year is different than calendar year) the method QuartersInYear is easily modified to handle this.

Jason
+1 - Simple, extensible, easy to verify and understand. Love it.
LBushkin
+1  A: 

Assuming quarters always end at 3 month intervals you could do:

Maybe not the best solution, but very easy to read and modify compared to other solutions offered.

public void 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)
    }
}
Aequitarum Custos
+1  A: 

Here's a simple function to give you the last day of the current quarter (assuming you're using a standard calendar).

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

Hope that helps.

Tom
A: 

A simple function can calculate the last days of the most recently completed month:

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