Reputation: 3284
I'm trying to find all quarters between 2 given dates.
For example if the current date is today(15 Jan 2013) and a date in the past is 01 Jan 2012, I should be getting the following result: Dec 2012 Sep 2012 June 2012 March 2012
I can kind of keep deducting 3 months from the current date, but that is not going to be accurate as the test below denotes:
[TestMethod]
public void FindAllQuaters_FromAGivenDate_TillAPastDate()
{
var dateFinder = new FindQuarter();
//Between Feb 2013 & Jan 2012
var dates = dateFinder.GetAllQuarters(new DateTime(2013, 02, 01), new DateTime(2012, 01, 01)).ToList();
Assert.IsTrue(dates.Count == 4);
Assert.IsTrue(dates.First().Month == 12);
Assert.IsTrue(dates.First().Year == 2012);
Assert.IsTrue(dates.Skip(1).First().Month == 9);
Assert.IsTrue(dates.Skip(1).First().Year == 2012);
Assert.IsTrue(dates.Skip(2).First().Month == 6);
Assert.IsTrue(dates.Skip(2).First().Year == 2012);
Assert.IsTrue(dates.Skip(3).First().Month == 3);
Assert.IsTrue(dates.Skip(3).First().Year == 2012);
}
}
public class FindQuarter
{
public IEnumerable<DateTime> GetAllQuarters(DateTime current, DateTime past)
{
while (current > past)
{
current = current.AddMonths(-3);
yield return current;
}
}
}
How can I achieve this? The quarters are defined as March,June,September & December. I would also need the last date of that month(which I hope would be quick).
EDIT: This is not working because it keeps deducting 3 months from a given date, for example if the current date is feb 2013 and I reduce 3 months,I get Nov 2012 and not December 2012.
Any dates in Jan,Feb,March will belong to first quarter i.e March
Any dates in April,May,June will belong to second quarter i.e June
Any dates in July,Aug,Sep will belong to third quarter i.e September
Any dates in Oct,Nov,Dec will belong to fourth quarter i.e December
Upvotes: 3
Views: 6787
Reputation: 141
Easy formula to get quarters difference
{
int firstQuarter = getQuarter(first);
int secondQuarter = getQuarter(second);
return 1 + Math.Abs(firstQuarter - secondQuarter);
}
private static int getQuarter(DateTime date)
{
return (date.Year * 4) + ((date.Month - 1) / 3);
}
Upvotes: 0
Reputation: 53
I know this is an old thread, but here is a Lambda expression to get you this information:
private static List<Tuple<DateTime, DateTime>> GetQuarterDates(DateTime startDate, DateTime endDate)
{
List<Tuple<DateTime, DateTime>> quarterDates = new List<Tuple<DateTime, DateTime>>();
quarterDates = Enumerable.Range(0, (endDate - startDate).Days)
.Where(x => startDate.AddMonths(x).Date == new DateTime(startDate.AddMonths(x).Year, (((startDate.AddMonths(x).Month - 1) / 3 + 1) - 1) * 3 + 1, 1))
.Select(x => new Tuple<DateTime, DateTime>(startDate.AddMonths(x), startDate.AddMonths(x + 3).AddDays(-1)))
.Where(x => x.Item2 <= endDate).ToList();
return quarterDates;
}
Upvotes: 1
Reputation: 1851
I would think you could use the %
operator. For example:
if (dt1.Month % 3 == 0)
{
// it is a quarter end, else it's not.
}
Upvotes: 1
Reputation: 22001
This seems to work.
public IEnumerable<DateTime> GetAllQuarters(DateTime current, DateTime past)
{
var curQ = (int)Math.Ceiling(current.Month / 3.0M);
var lastQEndDate = new DateTime(current.Year, curQ * 3, 1).AddMonths(-2).AddDays(-1);
do
{
yield return lastQEndDate;
lastQEndDate = lastQEndDate.AddMonths(-3);
} while (lastQEndDate > past);
}
Upvotes: 3
Reputation: 460018
You could use the class below i've written some time ago:
DateTime dt1 = new DateTime(2012, 1, 1);
DateTime dt2 = new DateTime(2013, 1, 15);
long countQuarters = Quarter.GetQuarters(dt1, dt2); // outputs 4
Quarter:
public class Quarter
{
public static long GetQuarters(DateTime dt1, DateTime dt2)
{
double d1Quarter = GetQuarter(dt1.Month);
double d2Quarter = GetQuarter(dt2.Month);
double d1 = d2Quarter - d1Quarter;
double d2 = (4 * (dt2.Year - dt1.Year));
return Round(d1 + d2);
}
private static int GetQuarter(int nMonth)
{
if (nMonth <= 3)
return 1;
if (nMonth <= 6)
return 2;
if (nMonth <= 9)
return 3;
return 4;
}
private static long Round(double dVal)
{
if (dVal >= 0)
return (long)Math.Floor(dVal);
return (long)Math.Ceiling(dVal);
}
}
Upvotes: 3