Get last 'N' quarters in C#
Suppose the current quater is 3 and the year is 2011. How can I get the last 5 quarters
Desired output:
Q3-2011
Q2-2011
Q1-2011
Q4-2010
Q3-2010
The Q and '-' is appended.
I am trying as under
int generateQuater = 5;
int currentQuater = 3;//GetQuarter(DateTime.Now.Month);
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>开发者_开发知识库();
lstQuaterYear.Add(string.Concat('Q',currentQuater, '-', currentYear));
for (int i = generateQuater; i > 0; i++)
{
//code to be placed
}
Thanks
You have to decrease your loop variable. The rest is not too difficult math. Its also not necessary to handle the first iteration in any special way:
for (int i = generateQuater; i > 0; i--)
{
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater, currentYear));
if (--currentQuater == 0)
{
currentQuater = 4;
currentYear--;
}
}
As a pure LINQ expression:
public IEnumerable<String> GetQuarters(int start, int year, int count)
{
return (from q in Enumerable.Range(0, count)
select String.Format("Q{0}-{1}", (start - q) + (((q + 1) / 4) * 4) , year - ((q + 1) / 4)));
}
The math is somewhat ugly but does work, to use it you can just do:
foreach (String quarter in GetQuarters(3, 2011, 5))
{
Console.WriteLine(quarter);
}
Your for loop should go from 0 to your variable, when you're increasing i.
The inner code could be something like:
currentQuarter--;
if(currentQuarter == 0)
{
currentQuarter = 4;
currentYear--;
}
Don't forget to refactor it :)
int count = 5;
int currentQuarter = GetQuarter(DateTime.Now.Month);
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
for (int i = count; i > 0; i--)
{
lstQuaterYear.Add(string.Concat('Q', currentQuarter, '-', currentYear));
currentQuarter--;
if (currentQuarter == 0)
{
currentQuarter = 4;
currentYear--;
}
}
One way is to check for year roll over and then set the quarter to 4 and decrement the year:
int quarter=3;
int year=2011;
int count=5;
for(int i=0;i<count;i++)
{
lstQuaterYear.Add(string.Format("Q{0} {1}", quarter, year);
quarter--;
if(quarter==0)
{
quarter=4;
year--;
}
}
Alternatively you could calculate a totalQuartal=year+quartal-1
. Then decrement it on each step. And finally use year=totalQuartal/4
and quartal=totalQuartal%4+1
. But I think the first way is easier to understand.
public static IEnumerable Generate(int number, int currentYear, int currentQuarter)
{
int counter = number;
int quarter = currentQuarter;
int year = currentYear;
while (counter-- > 0)
{
yield return String.Format("Q{0}-{1}", year, quarter);
quarter = quarter>1?quarter-1:4;
year = quarter==4?year-1:year;
}
}
Here is my version (sorry, it is in VB.NET).
The idea is to :
- easily find out the quarter based on a date (easy : divide it by 4 ... and add 1 to avoid zeros)
- go back in time from the current date, removing 3 month at each time
- printout the formatted quarter
the code :
Private Shared Function GetQuarterForDate(ByVal d As DateTime) As Integer
Return (d.Month \ 4) + 1 'integer division
End Function
Private Shared Function GetLastNQuarters(ByVal N As Integer) As IEnumerable(Of String)
Dim myDate = DateTime.Now
Dim res As New List(Of String)()
Do While N > 0
'using yield would be nicer in C# ... does not exist in VB
res.Add(String.Format("Q{0}-{1}", GetQuarterForDate(myDate), myDate.Year))
myDate = myDate.AddMonths(-3)
N = N - 1
Loop
Return res
End Function
<TestMethod()>
Public Sub CanRetrieveQuarter()
Dim quarters = GetLastNQuarters(5)
For Each q In quarters
Console.WriteLine(q)
Next
End Sub
That last "test method" prints out :
Q3-2011
Q2-2011
Q1-2011
Q4-2010
Q3-2010
In case you should do some operations on the quarter period, like check if moment is within a quarter, you can use the Quarter class of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public ITimePeriodCollection GetPastQuarters( int count )
{
TimePeriodCollection quarters = new TimePeriodCollection();
Quarter quarter = new Quarter();
for ( int i = 0; i < count; i++ )
{
quarters.Add( quarter );
quarter = quarter.GetPreviousQuarter();
}
return quarters;
} // GetPastQuarters
精彩评论