Реализовывая как то механизм получения всех дат для заданного дня недели определенного года для выстраивания их на виртуальном календаре при сравнении со сторонним списком дат, наткнулся на очень интересный (как по мне) вариант реализации схожей задачи (немного переделал для своих нужд):
class DataWorker
{
public IEnumerable GetAllDates(int year,
DayOfWeek dayOfWeek)
{
DateTime date;
for (int i = 1; i <= 12; i++)
{
date = new DateTime(year, i, 1);
var dates = Enumerable.Range
(
1,DateTime.DaysInMonth(date.Year,date.Month)).
Select(tempDay => new DateTime(
date.Year, date.Month, tempDay)
);
foreach (var item in dates)
if (item.DayOfWeek == dayOfWeek)
yield return item;
}
}
}
Для получения всех дат, соответствующих определенному (к примеру среда) дню недели в каждом месяце текущего года вызываем метод GetAllDates:
var dates = wdt.GetAllDates(2010, DayOfWeek.Wednesday);
Получив список, реализовывающий интерфейс IEnumerable, не составляет особого труда перебрать все его элементы. Ну к примеру хотя бы так:
foreach (var dat in dates)
Console.WriteLine(dat.ToString());
Для тех, кто впервые сталкивается с лямбда выражениями скажу, что хотя далеко не все программеры применяют их для подобных целей (и не только), все таки полезно познакомиться с их принципом работы и приемами составления.
Обещаю в скором времени познакомить вас с синтаксисом лямбда выражений, а пока для начала метод GetAllDates перепишем с более глубоким использованием лямбда выражений (пример кода тоже не мой, но очень уж понравился изящностью исполнения):
public IEnumerable GetAllDates(int year,
DayOfWeek weekDay)
{
return Enumerable.Range(1, 12)
.Select(month => new DateTime(year, month, 1))
.Select(date => Enumerable.Range(
1, DateTime.DaysInMonth(date.Year, date.Month))
.Select(day => new DateTime(date.Year, date.Month, day))
.Where(thisDay => thisDay.DayOfWeek == weekDay))
.SelectMany(d => d);
}
Вызов данного метода ничем не отличается от предыдущего:
var dates = wdt.GetAllDates(2010, DayOfWeek.Wednesday);
Тут же попутно, если требуется получить все месяцы в году:
System.Globalization.DateTimeFormatInfo dtformatInfo =
new System.Globalization.DateTimeFormatInfo();
for(int i = 1; i <= 12; i++)
Console.WriteLine(dtformatInfo.GetMonthName(i));
Если требуется проверить содержимое объекта на реальность даты, то:
//создается на случай успешного приведения в методе TryParse
DateTime errorvalue = new DateTime();
Console.WriteLine(DateTime.TryParse(
string.Format("{0} {1} {2}", DateTime.Now.Year,
DateTime.Now.Month, DateTime.Now.Day), out errorvalue));
Здесь разбираем пример определения даты в будущем и в прошлом.