54

The following are the Quarters for a financial year

April to June          - Q1
July to Sep            - Q2
Oct to Dec             - Q3
Jan to March           - Q4

If the month of an input date lies as above I need the output for in terms of Quarter number.

For Example,

If I give an input date (say january 2nd) , I need the output as Q4.

If I give input as (Jun 5), output should give Q1.

Based on input date I need the Quarter number.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
venkat
  • 5,648
  • 16
  • 58
  • 83

15 Answers15

94

If you prefer short and concise solutions without branching and arrays, here is my preferred solution.

Normal Quarter:

public static int GetQuarter(this DateTime date)
{
    return (date.Month + 2)/3;
}

Financial Year Quarter:

public static int GetFinancialQuarter(this DateTime date)
{
    return (date.AddMonths(-3).Month + 2)/3;
}

Integer division will truncate decimals, giving you an integer result. Place methods into a static class and you will have an extension method to be used as follows:

date.GetQuarter()
date.GetFinancialQuarter()

See dotnetfiddle

wezzix
  • 1,984
  • 1
  • 19
  • 18
31

You can simply write an extension method to DateTime

public static int GetQuarter(this DateTime date)
{
    if (date.Month >= 4 && date.Month <= 6)
        return 1;
    else if (date.Month >= 7 && date.Month <= 9)
        return 2;
    else if (date.Month >= 10 && date.Month <= 12)
        return 3;
    else 
        return 4;
}

and use it as

DateTime dt = DateTime.Now;
dt.GetQuarter();
Poul Bak
  • 10,450
  • 5
  • 32
  • 57
Haris Hasan
  • 29,856
  • 10
  • 92
  • 122
  • Thanks for your method. If the above method results '4' as output for january month then i need the output with some extra effort as Q4, Q1, Q2, Q3. Just rotation of these Quarters in a order wise based on the month of a datetime. How can i get? – venkat Jan 02 '12 at 07:24
  • Your requirement is not clear to me with your comment. Can you explain or better post it in a different question? The above piece of code answer your current question – Haris Hasan Jan 02 '12 at 08:08
22

The most simple and consistent way of achieving this:


Regular

Math.Ceiling(date.Month / 3.0)

Fiscal (just shifted up with a mod by 2+1 quarters)

Math.Ceiling(date.Month / 3.0 + 2) % 4 + 1

01.01.2016 00:00:00 -> Q1 -> FQ4
01.02.2016 00:00:00 -> Q1 -> FQ4
01.03.2016 00:00:00 -> Q1 -> FQ4
01.04.2016 00:00:00 -> Q2 -> FQ1
01.05.2016 00:00:00 -> Q2 -> FQ1
01.06.2016 00:00:00 -> Q2 -> FQ1
01.07.2016 00:00:00 -> Q3 -> FQ2
01.08.2016 00:00:00 -> Q3 -> FQ2
01.09.2016 00:00:00 -> Q3 -> FQ2
01.10.2016 00:00:00 -> Q4 -> FQ3
01.11.2016 00:00:00 -> Q4 -> FQ3
01.12.2016 00:00:00 -> Q4 -> FQ3

Result is a value between 1 and 4. Nearly any environment has a CEIL function, so this should work on any language as well.

Draken
  • 3,134
  • 13
  • 34
  • 54
Code Guru
  • 323
  • 3
  • 6
  • This looks good! but let's say I want a different start date. lets say `August` instead of `April`? Which value should I change? Thanks! – tastebuds Sep 06 '19 at 10:00
19

This is for the "normal year". I think you can adapt the sample:

string.Format("Q{0}", (date.Month + 2)/3);
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Dominik
  • 3,342
  • 1
  • 17
  • 24
13
public static int GetQuarter(DateTime date)
{
    int[] quarters = new int[] { 4,4,4,1,1,1,2,2,2,3,3,3 };
    return quarters[date.Month-1];
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Max Kilovatiy
  • 798
  • 1
  • 11
  • 32
8

Extension method and less comparisons:

public static class DateTimeExtension
{
    public static int GetQuarter(this DateTime dateTime)
    {
        if (dateTime.Month <= 3)
            return 1;

        if (dateTime.Month <= 6)
            return 2;

        if (dateTime.Month <= 9)
            return 3;

        return 4;
    }
}
Den
  • 1,827
  • 3
  • 25
  • 46
6
int CurrentQuarter = (int)Math.Floor(((decimal)DateTime.Today.Month + 2) / 3);

or change the DateTime.Today to required date.

ALT
  • 1,202
  • 11
  • 7
4

in sql, it's simply

((((month(@mydate)-1)/3)+3) % 4) + 1

check it with this:

declare @mydate datetime
set @mydate = '2011-01-01'
while @mydate <= '2011-12-31'
    begin
    print ((((month(@mydate)-1)/3)+3) % 4) + 1
    set @mydate = dateadd(month, 1, @mydate)
    end

Or if you want to do it in .net, it's like

String.Format("Q{0}", ((((date.Month-1)/3)+3) % 4) + 1);
Laszlo T
  • 1,165
  • 10
  • 22
2

Now that you have relational patterns in C# it can easily be written in a single switch expression

public static string FiscalQuarter(this DateTime date)
{
    var qtr = date.Month switch
    {
        < 4 => 4,
        < 7 => 1,
        < 10 => 2,
        _ => 3
    };
    return $"Q{qtr}";
}
Buvy
  • 1,174
  • 12
  • 16
2

We have the following quarters in a year

1 = (0 or 1 or 2)/3 + 1

2 = (3 or 4 or 5)/3 + 1

3 = (6 or 7 or 8)/3 + 1

4 = (9 or 10 or 11)/3 + 1

public static int GetQuarter(this DateTime source)
{
   return (source.Month - 1) / 3 + 1;
}
1

You can simply do this:

for (int i = 1; i <= 12; i++) { 
    Console.WriteLine("Month {0} - Q{1}", i, Math.Ceiling((i <= 3 ? 12 - i + 1 : i - 3) / 3M));
}

The output will be: enter image description here

Chuck Conway
  • 16,287
  • 11
  • 58
  • 101
boossss
  • 1,006
  • 8
  • 7
  • forget the cast to int of the Math.Ceiling (in the image), I was doing some tests and forgot to remove it. – boossss Dec 29 '15 at 13:12
1

This method allows you to specify the start month of the quarter and also provides the year(s) for the period as a whole.

    public string GetQuarterPeriod(DateTime date, int quarterStartMonth)
    {
        var quarterDateOffset = date.AddMonths(1 - quarterStartMonth);
        return $"Q{Math.Ceiling((decimal)quarterDateOffset.Month / 3)} {quarterDateOffset.Year}" 
               + (quarterStartMonth == 1 ? "" : $"/{quarterDateOffset.Year + 1}");
    }

Giving:

GetQuarterPeriod(new DateTime(2018, 4, 1), 4) -> "Q1 2018/2019"
GetQuarterPeriod(new DateTime(2018, 1, 1), 1) -> "Q1 2018"

Function accounts for the fact that if the month is January (1) it is constrained to a single year.

Mark
  • 880
  • 8
  • 18
1

I came here looking to create a DateTime for the first day of a given a quarter and year (which is understandably the opposite of the question above, but related) and adopted @wezzix's answer above to create:

public DateTime GetFirstDayOfQuarterFromYearAndQuarter(int year, int quarter)
{
    var month = 3 * quarter - 2;

    return new DateTime(year, month, 1);
}
Kurtis Jungersen
  • 2,204
  • 1
  • 26
  • 31
1

why not simply use Math.Ceiling to get quarter and then decide what you want for a particular quarter, see this:

var quarter = (int)System.Math.Ceiling((decimal)DateTime.Now.Month/3);
var arrayPosition = new int[] { 4, 1, 2, 3 };
var result = arrayPosition[quarter - 1];
Ali Adravi
  • 21,707
  • 9
  • 87
  • 85
0

"Data structures OR Algorithms" (i.e. Nicolaus Wirth's "Algorithms and Data Structures" done right). I thus would avoid any calculation and instead would just look it up.

private static readonly Dictionary<int, string> FiscalQuarters = new Dictionary<int, string>
{
        {1, "Q4"}, {2, "Q4"}, {3, "Q4"}, 
        {4, "Q1"}, {5, "Q1"}, {6, "Q1"}, 
        {7, "Q2"}, {8, "Q2"}, {9, "Q2"}, 
        {10, "Q3"}, {11, "Q3"}, {12, "Q3"}
};

public static void Main()
{
    var a = new DateTime(2020, 1, 26);      
    Console.WriteLine(FiscalQuarters[a.Month]);
}

For further reading just google "time dimension table"...