0

Say I have a timeframe defined by two DateTime objects, d1 and d2.

How could I know the number of times the first day of a month is in the timeframe?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
razonasistemas
  • 371
  • 1
  • 4
  • 11
  • add a sample code to explain your question more – Monah Feb 26 '15 at 21:00
  • do you mean for example between 31 Dec 2014 and 23 Mar 2015, how many days which its the first day? ( 01 Jan, 01 Feb, 01 Mar)? 3 times, something like this ? – Monah Feb 26 '15 at 21:02
  • possible duplicate of [Difference in months between two dates](http://stackoverflow.com/questions/4638993/difference-in-months-between-two-dates) – Wai Ha Lee Feb 26 '15 at 23:07

3 Answers3

3

You could something like:

DateTime startDate = DateTime.Now.AddDays(-100); // {18/11/2014 4:04:07 PM}
DateTime endDate = DateTime.Now; // {26/02/2015 4:04:07 PM}
var query = Enumerable.Range(0, 1 + (endDate - startDate).Days)
    .Select(i => startDate.AddDays(i))
    .Where(r=> r.Day == 1);

This will first create a collection of dates from start to end, and later you can filter the results where Day part is 1.

For output:

foreach (var dateTime in query)
{
    Console.WriteLine(dateTime);
}

Output:

01/12/2014 4:04:07 PM
01/01/2015 4:04:07 PM
01/02/2015 4:04:07 PM
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 1
    I'm sure there is a way that doesn't require you to enumerate over a collection of dates. Simple arithmetic should do the trick. But it's still a valid answer. – MarcinJuraszek Feb 26 '15 at 21:05
  • 1
    This is a brute force way to do it. I worry about the performance of this if I need to calculate all the 1st of the month between Jan 1st 100 to Mar 5 25000 – thorkia Feb 26 '15 at 21:19
  • @thorkia, created [another solution](http://stackoverflow.com/a/28753238/961113) which calculates dates from `1-1-1` to `9999-12-31` in no time. – Habib Feb 26 '15 at 21:41
  • @thorkia, only max allowed for `DateTime` in .Net is `9999` year, and this bruit force method would take less than a second. – Habib Feb 26 '15 at 21:57
2

Another approach without the previous bruit force....


DateTime startDate = new DateTime(2014, 09, 01);
DateTime endDate = new DateTime(2015, 02, 02);
DateTime loopDate = startDate;
var totalMonths = ((endDate.Year - startDate.Year) * 12) + endDate.Month - startDate.Month;
if (startDate.Day != 1)
{
    loopDate = new DateTime(startDate.Year, startDate.Month, 1).AddMonths(1);
}

List<DateTime> firstDayOfMonth = Enumerable.Range(0, totalMonths)
    .Select(i => loopDate.AddMonths(i))
    .ToList();

firstDayOfMonth.Add(new DateTime(endDate.Year,endDate.Month, 1));

This calculates the months difference based on solution provided here. Later it checks if the startDate is the first day of month then ignore it, and creates a loopDate which would be next available first day of month, and continues till endDate.

Here is a working .Net fiddle

Community
  • 1
  • 1
Habib
  • 219,104
  • 29
  • 407
  • 436
0

This is simple math.

D1: Jan 23rd 2015 D2: Mar 2nd 2015

Find the number of months that have passed (d2.Month - d1.Month).

That gives you the number of first of the months that have passed.

Edge cases you will need to consider:

  1. D1 is the first day of the month - just do a simple check for that and add 1 to the result
  2. D1 and D2 year is different - this is simple as well:
    2.1. Calculate months between D1 and the end of its year (IE: D1 to Dec 31st), then make sure to check edge case 1.

    2.2. Calculate the months between D2 and the start of its year (IE: Jan 1st to D2)

    2.3. After that, add 12 for every year difference greater than 1 (it means more than one year has passed - D1 is 2010 and D2 is 2013 - 2 whole years have passed. Step one caclulated the months in 2010, and step 2 for 2013.

    2.4. Add the results of steps 1,2, and 3 together.

thorkia
  • 1,972
  • 1
  • 20
  • 26
  • 1
    You don't need to work out months from D1 to the end of the year and from the start to D2. For instance, D1 = 15 Dec 2013; D2 = 20 Jan 2014. (2014-2103)*12 + {Jan - Dec = -11} = 1. – Wai Ha Lee Feb 26 '15 at 22:18