Maritim
Maritim

Reputation: 2159

Calculating first month of the current or next yearly quarter and the last month of the current yearly quarter based on a given date

Given a date I wish to calculate the current yearly quarter.

If today's date is greater than the given date I wish to calculate the last month of the current yearly quarter based on the given date, and the first month of the next yearly quarter.

The quarters I operate with are jan-mar, apr-jun, jul-sep and oct-dec.

In the event that the date input is 01/10/2013 I wish the output to be january (the first month of the next yearly quarter) and december (the last month of the current yearly quarter). In this case the month variable would contain the value 10 and the day variable would contain the value 1.

My attempts so far:

Last month of each quarter

if (month % 3 == 0)
  month += (DateTime.Now.Day > day ? 3 : 0);
if (month % 3 == 1)
  month += 2;
if (month % 3 == 2)
  month += 1;

First month of each quarter

if (month % 3 == 1) // jan/mapr/jul/oct
  month += (DateTime.Now.Day > day ? 3 : 0);
if (month % 3 == 2) // feb/may/aug/nov
  month += 2;
if (month % 3 == 0) // mar/jun/sep/dec
  month += 1;

Upvotes: 1

Views: 3966

Answers (6)

user687474
user687474

Reputation:

You can use the Quarter class of the Time Period Library for .NET:

// ----------------------------------------------------------------------
public void QuarterStartEndMonth()
{
  DateTime now = DateTime.Now;

  Quarter pastQuarter = GetQuarter( new DateTime( now.Year - 1, 10, 1 ) );
  Console.WriteLine( "Quarter last month {0:d}", pastQuarter.LastMonthStart );
  Console.WriteLine( "Next quarter start month {0:d}",
    pastQuarter.GetNextQuarter().Start );

  Quarter futureQuarter = GetQuarter( new DateTime( now.Year + 1, 10, 1 ) );
  Console.WriteLine( "Quarter last month {0:d}", futureQuarter.LastMonthStart );
  Console.WriteLine( "Next quarter start month {0:d}",
    futureQuarter.GetNextQuarter().Start );
} // QuarterStartEndMonth

// ----------------------------------------------------------------------
private Quarter GetQuarter( DateTime moment )
{
  DateTime now = DateTime.Now;
  return new Quarter( now > moment ? now : moment );
} // GetQuarter

Upvotes: 0

Nicholas Carey
Nicholas Carey

Reputation: 74177

These helper methods ought to give you everything you need:

public static class DateTimeHelpers
{
    private static DateTime StartDateOfCurrentQuarter( DateTime instant )
    {
        return new DateTime( instant.Year , 1 + 3*((instant.Month-1)/3) , 1 ) ;
    }
    public static void CurrentQuarter( this DateTime instant , out DateTime start , out DateTime end )
    {
        start = StartDateOfCurrentQuarter(instant) ;
        end   = start.AddMonths(3).AddTicks(-1) ;
        return ;
    }
    public static void NextQuarter( this DateTime instant , out DateTime start , out DateTime end )
    {
        start = StartDateOfCurrentQuarter(instant).AddMonths(3) ;
        end   = start.AddMonths(3).AddTicks(-1) ;
        return ;
    }
    public static void PrevQuarter( this DateTime instant , out DateTime start , out DateTime end )
    {
        start = StartDateOfCurrentQuarter(instant).AddMonths(-3) ;
        end   = start.AddMonths(3).AddTicks(-1) ;
        return ;
    }
}

Upvotes: 0

Chris
Chris

Reputation: 27599

You can get the current quarter using integer maths.

int currentQuarter = ((month-1)/3)+1;

This works because integer division will always truncate so if month is 1 to 3 you will get 0 to 2 over 3 which will equal 0. month 4 to 6 will give 3-5 over 3 which will equal 1 and so on.

For a given quarter the first and last month will be given by:

int firstMonthOfQuarter = (quarter*3)-2;

and

int lastMonthOfQuarter = (quarter*3);

Note that the quarter in these will be the quarter you want the month for. If you want the current quarter then use that. If you want the next quarter then do quarter+=1 and check for overflow (ie if quarter is 5 then it is actually 1). Alternatively you could add %12 onto the first and last month calculations and then it will work fine with a quarter of 5.

int firstMonthOfQuarterOfNextQuarter = (((quarter+1)*3)-2)%12;
int lastMonthOfQuarterOfNextQuarter = ((quarter+1)*3)%12;

I'm a little confused as to how you want to put this together since you either want the current quarter (as given in my first line) or in some cases additionally the first and last month of the next and the current quarter. How you are returning this I don't know so you'll have to put it together yourself.

Upvotes: 5

user2480047
user2480047

Reputation:

As discussed, this algorithm delivers the functionality you want:

int quarterCurr = 1;
if (Convert.ToDouble(curMonth) / 3.0 > 1.0)
{
    quarterCurr = Convert.ToInt32(Convert.ToDouble(curMonth) / 3.0);
    if (curMonth % 3 != 0)
    {
        quarterCurr = quarterCurr + 1;
    }
}
int firstMonthCurr = 3 * (quarterCurr - 1) + 1;
int lastMonthCurr = 3 * quarterCurr;

int quarterNext = quarterCurr + 1;
if (quarterNext > 4)
{
    quarterNext = 1;
}
int firstMonthNext = 3 * (quarterNext - 1) + 1;

This a simple/clear way to calculate all the information you need: first/last month of each quarter.

This code is expected to be put in a function, which will be called when required. It will take, as input, just the current month and, as output, return a 1D array with a length of 2: first position for the last month of the current quarter and second position for the first month of the next quarter (or any other alternative). Thus, the main functionality (calculating the target values for any input month) is included but you are the one who has to adapt it to your exact requirements.

Upvotes: 1

Martijn van Put
Martijn van Put

Reputation: 3313

Write a wrapper class that gives the First or Last month based on the current date time and gives the Name of the month from the CurrentCulture settings

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Quater.GetFirstMonth(DateTime.Now.Month)); // Outputs october
        Console.WriteLine(Quater.GetLastMonth(DateTime.Now.Month)); // Outputs september

        Console.ReadLine();
    }
}

public static class Quater
{
    public static string GetFirstMonth(int month)
    {
        if (month >= 1 && month <= 3) {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(4);
        }
        if (month >= 4 && month <= 6) {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(7);
        }
        if (month >= 7 && month <= 9) {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(10);
        }
        if (month >= 10 && month <= 12) {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(1);
        }

        return string.Empty;
    }

    public static string GetLastMonth(int month)
    {
        if (month >= 1 && month <= 3)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(3);
        }
        if (month >= 4 && month <= 6)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(6);
        }
        if (month >= 7 && month <= 9)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(9);
        }
        if (month >= 10 && month <= 12)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(12);
        }

        return string.Empty;
    }
}

Upvotes: 0

Cubicle.Jockey
Cubicle.Jockey

Reputation: 3328

var currentDate = DateTime.Now;
var quarterNumber = ((currentDate.Month-1)/3) + 1;
var firstDayOfQuarter = new DateTime(currentDate.Year, ((quarterNumber-1) * 3) + 1, 1);
var lastDayOfQuarter = firstDayOfQuarter.AddMonths(3).AddDays(-1);

Upvotes: 0

Related Questions