С# Месяц и день Возникновение между датами
У меня есть месяц и день, и мне нужно искать каждый месяц и день в этом списке между датами. Может ли кто-нибудь предложить мне сделать лучший способ получить желаемый результат.
Например:
Месячный дневной список → 01/11, 03/15, 05/25, 09/01
Между датами → 01/01/2012 по 07/01/13
Ожидаемый результат:
01/11/2012, 01/11/2013
03/15/2012, 03/15/2013
05/25/2012, 05/25/2013
09/01/2012
Я пробовал, как это, но это дает исключение памяти, а время и объем памяти увеличиваются, если с даты и до сегодняшнего дня, имея пробел в несколько лет, есть ли быстрое решение для его получения?
DateTime[] dateDates = new DateTime[dateTypeList.Rows.Count];
//convert strings to datetimes:
for (int i = 0; i < dateTypeList.Rows.Count; i++)
{
dateDates[i] = Convert.ToDateTime(Convert.ToDateTime(string.Format("{0}/{1}", Convert.ToInt32(dateTypeList.Rows[i]["Month"]), Convert.ToInt32(dateTypeList.Rows[i]["Day"]))));
}
//define start and end time:
DateTime dateStart = new DateTime(2012, 1, 1);
DateTime dateEnd = new DateTime(2013, 7, 1);
List<DateTime> results = new List<DateTime>();
//loop days between start and end time:
for (DateTime a = dateStart; a <= dateEnd; a.AddDays(1))
{
for (int i = 0; i < dateDates.Length; i++)
{
if (dateDates[i] == a)
{
results.Add(a);
}
}
}
EDIT: Хорошо, теперь я вижу больше о том, чего вы пытаетесь достичь.
Итак, у вас есть вход:
- Дата начала и дата окончания
Список пар месяц/день. В настоящее время у вас на самом деле нет этого, но это то, что вы логически получили.
В вашем текущем коде не учитывается тот факт, что может быть несколько лет.
Сначала измените вашу таблицу данных соответствующим образом:
var monthDays = dateTypeList.Rows.AsEnumerable()
.Select(row => new { Month = row.Field<int>("Month")
Day = row.Field<int>("Day") })
.ToList();
Теперь вы можете использовать:
for (int year = startDate.Year; year <= endDate.Year; year++)
{
foreach (var pair in monthDays)
{
// Avoid creating a date which doesn't exist...
if (!DateTime.IsLeapYear(year) && pair.Month == 2 && pair.Day == 29)
{
continue;
}
DateTime date = new DateTime(year, pair.Month, pair.Day);
if (date <= startDate && date <= endDate)
{
results.Add(date);
}
}
}
Это непосредственная проблема:
for (DateTime a = dateStart; a <= dateEnd; a.AddDays(1))
DateTime неизменен, поэтому AddDays
не действует, если вы не используете возвращаемое значение. Вы хотите:
for (DateTime a = dateStart; a <= dateEnd; a = a.AddDays(1))
Я также изменил бы этот код:
dateDates[i] = Convert.ToDateTime(
Convert.ToDateTime(string.Format("{0}/{1}",
Convert.ToInt32(dateTypeList.Rows[i]["Month"]),
Convert.ToInt32(dateTypeList.Rows[i]["Day"]))));
- Это происходит через строковое представление без причины
Он вызывает
Convert.ToDateTime
дважды без причиныПредполагается, что формат системной даты - месяц/день, который является специфичным для культуры.
public class Class1
{
public static void Main()
{
var dayList = new List<customMonthDay>{
new customMonthDay{ Day = 11, Month = 1 },
new customMonthDay{ Day = 15, Month = 3 },
new customMonthDay{ Day = 25, Month = 5 },
new customMonthDay{ Day = 1, Month = 9 }
};
var startDate = new DateTime( 2012, 1, 1 );
var endDate = new DateTime( 2013, 7, 1 );
var listYears = getYears(startDate, endDate);
var includedDays = new List<customMonthDayYear>();
foreach (var year in listYears)
{
foreach (var day in dayList)
{
var candidateday = new customMonthDayYear { Year = year, Month = day.Month, Day = day.Day };
if (candidateday.ToDateTime() > startDate && candidateday.ToDateTime() < endDate)
includedDays.Add(candidateday);
}
}
includedDays.ForEach(x => Console.WriteLine(x.ToDateTime().ToString()));
}
protected static List<int> getYears(DateTime start, DateTime end)
{
var years = new List<int>();
int diff = end.Year - start.Year;
for ( int i = 0; i <= diff; i++ )
{
years.Add( start.Year + i );
}
return years;
}
public class customMonthDay
{
public int Day { get; set; }
public int Month { get; set; }
}
public class customMonthDayYear : customMonthDay
{
public int Year { get; set; }
public DateTime ToDateTime()
{
return new DateTime(Year, Month, Day);
}
}
}
Это работает для меня, но есть ли способ уменьшить это, используя linq или что-то еще?
private List<DateTime> GetDates(DataTable dateTypeList, DateTime fromDate, DateTime toDate)
{
List<DateTime> results = new List<DateTime>();
fromDate = Convert.ToDateTime(fromDate.ToShortDateString());
toDate=Convert.ToDateTime(toDate.ToShortDateString());
int minDay = fromDate.Day;
int minMonth = fromDate.Month;
int minYear = fromDate.Year;
int maxDay = toDate.Day;
int maxMonth = toDate.Month;
int maxYear = toDate.Year;
for (int j = minYear; j <= maxYear; j++)
{
for (int i = 0; i < dateTypeList.Rows.Count; i++)
{
int _day = Convert.ToInt32(dateTypeList.Rows[i]["Day"]);
int _month = Convert.ToInt32(dateTypeList.Rows[i]["Month"]);
DateTime tempDate = new DateTime(j, _month, _day);
if ((tempDate >= fromDate) && (tempDate <= toDate))
{
results.Add(tempDate);
}
}
}
return dateTypeList;
throw new NotImplementedException();
}
используйте следующее:
for each date in list
a.Equals(date) or a.CompareTo(date)