0

I want to extract all the sundays in the current month and have this code:

 private string GetDatesOfSundays(DateTime DatMonth)
 {
  string sReturn = "";
  int iDayOffset = DatMonth.Day - 1;
  DatMonth = DatMonth.AddDays(System.Convert.ToDouble(-DatMonth.Day + 1));
  DateTime DatMonth2 = DatMonth.AddMonths(1).AddDays(System.Convert.ToDouble(-1));
  while (DatMonth < DatMonth2)
  {
    if (DatMonth.DayOfWeek == System.DayOfWeek.Sunday)
    {
      if (sReturn.Length > 0) sReturn += ",";
      sReturn += DatMonth.ToShortDateString();
    }
    DatMonth = DatMonth.AddDays(1.0);
  }
  return sReturn;
}   

[HttpGet]
public ActionResult TradeUKKPISearchesData()
{
  string allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now);  
  //var reportData = _reportingService.GetTradeUKKPISearches();
  //return View(reportData);
}

the problem lies with my type string for allSundaysInMonth and is also empty ofcourse. The sReturn is of type string but then again I pass a date(I know :) ) but what type should allSundaysInMonth be? sReturn does have the correct dates in...I need to display these dates in a dropdown in the view of the controller so the user can select any of the sundays for which he/she needs to run a report for.

thanks

charlie_cat
  • 1,830
  • 7
  • 44
  • 73
  • 2
    `IEnumerable` looks good to me – Jodrell Aug 03 '12 at 09:44
  • I tried: IEnumerable allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now); and it gives error Cannot implicitly convert type 'string' to 'System.Collections.Generic.IEnumerable' :( – charlie_cat Aug 03 '12 at 09:48
  • @charlie, you *can* declare your variable as `string` and the method's return type as `IEnumerable`, but don't expect the two to fit together. One is a sequence of dates, the other is a bunch of characters. Not the same types at all, thus you can't assign one to the other. – stakx - no longer contributing Aug 03 '12 at 09:51

2 Answers2

5

How about

private IEnumerable<DateTime> GetDatesOfSundays(DateTime DatMonth)
{
    int iDayOffset = DatMonth.Day - 1;   
    DatMonth = DatMonth.AddDays(System.Convert.ToDouble(-DatMonth.Day + 1));
    DateTime DatMonth2 =
        DatMonth.AddMonths(1).AddDays(System.Convert.ToDouble(-1));
    while (DatMonth < DatMonth2)
    {
        if (DatMonth.DayOfWeek == System.DayOfWeek.Sunday)
        {
            yield return DatMonth;
        }

        DatMonth = DatMonth.AddDays(1.0);
    }
}

I would be tempted to rewrite your function as an extension somthing like this

public static IEnumerable<Datetime> DaysOfMonth(
    this DateTime any,
    DayOfWeek day)
{
    // start at first of month
    var candidate = new DateTime(any.Year, any.Month, 1);

    var offset = (int)day - (int)candidate.DayOfWeek;

    if (offset < 0)
    {
        offset += 7
    }

    candidate = candidate.AddDays(offset);

    while (cadidate.Month == any.Month)
    {
        yield return candidate;
        candidate = candidate.AddDays(7.0)
    }
}

Then you could use it like this

var allSundaysInMonth = DateTime.Now.DaysOfMonth(DayOfWeek.Sunday);

If you want to convert an IEnumerable<DateTime> to a string you could do this,

var listOfDates = string.Join<DateTime>(", ", allSundaysInMonth);

using this string.Join overload


If you really want the days as a DateTime[] you could do this (but there is no need)

DateTime[] allSundaysInMonth = GetDatesOfSundays(DateTime.Now).ToArray();

or for my extension example

var allSundaysInMonth = DateTime.Now.DaysOfMonth(DayOfWeek.Sunday).ToArray();
Jodrell
  • 34,946
  • 5
  • 87
  • 124
  • oooo ok sorry I have never worked with IEnumerable..I see/understand now..thanks! – charlie_cat Aug 03 '12 at 09:52
  • @charlie_cat learn about `IEnumerable` so you can unlock the power of linq – Jodrell Aug 03 '12 at 10:22
  • @charlie_cat I optimised the extension method to avoid needless iteration. – Jodrell Aug 03 '12 at 10:35
  • @charlie_cat tweaked for the last time. – Jodrell Aug 03 '12 at 10:59
  • I opted to use the DateTime[], I understand that better but have one more question on the calling line: DateTime[] allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now); when I debug and hover over allSundaysInMonth there is nothing and in DateTime[] I do not get the correct values as shoud be, and I get in return lst.ToArray();? thanks so much – charlie_cat Aug 03 '12 at 11:03
  • @charlie_cat `.ToArray()` is an extension to any `IEnumerable` so you can put `.ToArray()` on the end of my function call and it will give you an array instead. As for your specific problem, I suspect you need to execute the line to assign a value to the variable. Try stepping to the next line and looking at the value of `allSundaysInMonth` – Jodrell Aug 03 '12 at 11:10
  • I did step onto the next line though and still when i hover over the dateTime part I get a minValue,MaxValue,No,Today and uctToday?? and on my variable there is nothing...very odd – charlie_cat Aug 03 '12 at 11:32
  • @charlie_cat those are the properties of the DateTime structure. – Jodrell Aug 03 '12 at 13:03
0

You can go for DateTime[] or IEnumerable<DateTime>.

Your method signature should be

private IEnumerable<DateTime> GetDatesOfSundays(DateTime DatMonth)

or

private DateTime[] GetDatesOfSundays(DateTime DatMonth)

If you havn't worked with IEnumerable go for this

private DateTime[] GetDatesOfSundays(DateTime DatMonth)
{
    List<DateTime> lst = new List<DateTime>();

    DatMonth = DatMonth.AddDays(-DatMonth.Day + 1);
    DateTime DatMonth2 = DatMonth.AddMonths(1).AddDays(System.Convert.ToDouble(-1));

    while (DatMonth < DatMonth2)
    {
        if (DatMonth.DayOfWeek == System.DayOfWeek.Sunday)
        {
            lst.Add(DatMonth);
            DatMonth = DatMonth.AddDays(7);
            continue;
        }

        DatMonth = DatMonth.AddDays(1);
    }

    return lst.ToArray();
}

and call it as

DateTime[] allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now);
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • Why return an array whan you have just built a list? `IList` would be simpler. – Jodrell Aug 03 '12 at 10:24
  • Just one more question please..I went with the example above, the return lst.ToArray(); contains the correct info but the calling line: DateTime[] allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now); does not, there is nothing in allSundaysInMonth? – charlie_cat Aug 03 '12 at 10:29
  • @charlie_cat: Its working fine at my end. `allSundaysInMonth` gets for this month 4 dates namely 5,12,19,26. I have modified my answer to be more quick. Please check and let me know. Also tell me for which month and year are you trying where you are getting nothing. – Nikhil Agrawal Aug 03 '12 at 11:44
  • I added the extra two lines but still nothing in my variable yes those are the dates in the return lst.ToArray(); thanks.. something somewhere not right though...i will check my code again. thanks – charlie_cat Aug 03 '12 at 12:06
  • @charlie_cat: Is this running in Release or Debug mode? – Nikhil Agrawal Aug 03 '12 at 12:09
  • release, I see...should it be debug? – charlie_cat Aug 03 '12 at 12:14
  • there you go! i changed it to debug mode and voila! thank you so much every body!! – charlie_cat Aug 03 '12 at 12:17
  • @charlie_cat: The reason is this. http://stackoverflow.com/questions/2446027/c-sharp-debug-vs-release-performance. Read AZ answer's first point. That is reason for your problem. If you want to be in release mode. after this `DateTime[] allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now);` do this `allSundaysInMonth = allSundaysInMonth;` – Nikhil Agrawal Aug 03 '12 at 12:21