4

我有一个月和日列表,我需要在给定日期之间搜索此列表中的每个月和日。任何人都可以建议我做最好的方法来获得所需的输出。

例如:

月日列表 -> 01/11、03/15、05/25、09/01

日期之间 -> 2012 年 1 月 1 日至 2013 年 7 月 1 日

预期结果:

2012 年 1 月 11 日,2013 年 1 月 11 日

2012 年 3 月 15 日,2013 年 3 月 15 日

2012 年 5 月 25 日,2013 年 5 月 25 日

2012 年 9 月 1 日

我试过这样,但如果从日期到迄今为止有年数的差距,它会给内存异常和时间和内存复杂性增加,有没有快速的解决方案来获得它?

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);
        }
    }
}
4

4 回答 4

3

编辑:好的,现在我看到了更多关于你想要实现的目标。

所以你有输入:

  • 开始日期和结束日期
  • A list of month/day pairs. Currently you don't actually have this, but that's what you've logically got.

Your current code doesn't take account of the fact that there can be multiple years at all.

First, let's transform your data table appropriately:

var monthDays = dateTypeList.Rows.AsEnumerable()
                            .Select(row => new { Month = row.Field<int>("Month")
                                                 Day = row.Field<int>("Day") })
                            .ToList();

Now you can use:

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);
        }
    }
}

This is the immediate problem:

for (DateTime a = dateStart; a <= dateEnd; a.AddDays(1))

DateTime is immutable, so AddDays has no effect if you don't use the return value. You want:

for (DateTime a = dateStart; a <= dateEnd; a = a.AddDays(1))

I'd also change this code:

dateDates[i] = Convert.ToDateTime(
  Convert.ToDateTime(string.Format("{0}/{1}", 
      Convert.ToInt32(dateTypeList.Rows[i]["Month"]), 
      Convert.ToInt32(dateTypeList.Rows[i]["Day"]))));
  • It's going via a string representation for no reason
  • It's calling Convert.ToDateTime twice for no reason
  • It's assuming that the system date format is month/day, which is culture-specific
于 2012-11-07T07:18:38.663 回答
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);
        }
    }
}
于 2012-11-07T07:20:05.463 回答
0

使用以下:

for each date in list

 a.Equals(date) or a.CompareTo(date)
于 2012-11-07T06:43:33.337 回答
0

This works for me, but is there any way still we can reduce this one by using linq or something?

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();
        }
于 2012-11-07T09:19:31.830 回答