2012-11-07 4 views
4

У меня есть месяц и день, и мне нужно искать каждый месяц и день в этом списке между датами. Может ли кто-нибудь предложить мне сделать лучший способ получить желаемый результат.C# Месяц и день Происшествие между датами

Например:

месяц день список -> 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); 
     } 
    } 
} 
+2

Покажите нам код для Вашего списка – Habib

+1

дать мне Teh codez пожалуйста? – DarthVader

+0

@Habib месяц и день существуют в столбцах таблицы данных по столбцам месяца и дня. – user1805169

ответ

3

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 дважды без причины
  • Это при условии, что, что системный формат даты - месяц/день, который относится к культуре
+0

Большое вам спасибо! – user1805169

+0

Есть ли способ оптимизировать код выше, а не for и foreach? – user1805169

0

использовать следующее:

for each date in list 

a.Equals(date) or a.CompareTo(date) 
+0

Тогда будет огромный шанс, что никакие даты никогда не будут включены в результаты. – rikitikitik

+0

Ну, это определенно путь. Способ умнее проверять введенные даты, а не все даты между началом и временем окончания. Sry не понимал, что после этого @rikitikitik прокомментировал предыдущий код, который я согласен, выглядел немного не так: D – WozzeC

+0

@rohank 'не получаю вам код, который не ясен для меня. – user1805169

2
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); 
     } 
    } 
} 
+0

Что делать, если getyears zero? – user1805169

+0

Это просто быстрый образец с жестко закодированными данными. Просто чтобы указать, как избежать кошмара в культуре :) Я также не проверяю getYears, если начало <конец, и я должен. – Jordi

0

Это работает для меня, но есть ли способ все-таки мы можем уменьшить этот с помощью 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(); 
     } 
Смежные вопросы