查找下一个最近的日期
我有一些日期当前存储为字符串列表。
例如:
List dates = new List(); dates.Add("1/10/14"); dates.Add("2/9/14"); dates.Add("1/15/14"); dates.Add("2/3/14"); dates.Add("2/15/14");
(日期格式为mm/dd/yy
)
我将采用用户的输入(也以mm/dd/yy
格式),但作为字符串。
现在,我想在数组中找到用户输入日期后最接近的日期。
例如,如果用户输入"1/13/14"
,则输出应为"1/15/14"
。 如果用户输入"2/5/14"
,则下一个最近的日期是"2/9/14"
。 但是如果用户输入的日期晚于最后一个日期(例如"3/1/14"
,它将仍然返回数组中的最后一个日期,即"2/15/14"
)
我知道在某些时候你必须转换为类型DateTime,但我无法弄清楚找到这样的日期的逻辑。
List dates = new List (); dates.Add("1/10/14"); dates.Add("2/9/14"); dates.Add("1/15/14"); dates.Add("2/3/14"); dates.Add("2/15/14"); var allDates = dates.Select(DateTime.Parse).OrderBy(d=>d).ToList(); var inputDate = DateTime.Parse("1/13/14"); var closestDate = inputDate >= allDates.Last() ? allDates.Last() : inputDate <= allDates.First() ? allDates.First() : allDates.First(d => d >= inputDate);
现在我只是解析字符串,但你应该单独处理它。 这是简单明了的LINQ,你可以去看看并做二分搜索。
这是一个使用二进制搜索的解决方案。
你需要有一个DateTime
列表,对此毫无疑问。 没有必要将它们保持为string
s,如果必须的话,在进入列表的路上解析它们。 您可以使用LINQ转换列表中的所有元素,但这是您能够相互比较日期的唯一方法。
查看BinarySearch
页面,了解为什么我在返回值上使用按位运算符。
//build list of random dates Random r = new Random(); var dates = new List(); for (int i = 0; i < 10; i++) { dates.Add(new DateTime(2014, r.Next(1,13), r.Next(1,28))); } //sort list (if you don't do this, you'll most likely get the wrong answer) dates.Sort(); //get input string input = "1/13/14"; DateTime inputDate = DateTime.Parse(input); //find nearest var result = dates.BinarySearch(inputDate); DateTime nearest; //get match or next in list. if(result >= 0) nearest = dates[result]; else if (~result == dates.Count ) nearest =dates.Last(); else nearest = dates[~result];
如果您需要找到真正最接近的,请使用它代替最后一个if
块。
//get match, or true nearest date in list if(result >= 0) //date was found! Use that index. nearest = dates[result]; else if (~result == 0) //date not found, smaller than any item in the list. use first index. nearest = dates.First(); else if(~result == dates.Count) //date was not found, and is greater than all items. Use last index. nearest = dates.Last(); else //date not found, somewhere in the middle of the list. find the nearest date { var daysAfter = dates[~result].Subtract(inputDate); //date after input var daysBefore = inputDate.Subtract(dates[~result - 1]); //date before input if(daysAfter < daysBefore) nearest = dates[~result]; else nearest = dates[~result - 1]; }
DateTime searchDate = new DateTime(2014,03,01); var orderedDates = dates .Select(d => DateTime.ParseExact(d, "M/d/yy", CultureInfo.InvariantCulture)) .OrderBy(d => d).ToList(); var result = orderedDates.FirstOrDefault(d => d > searchDate); if (result == default(DateTime)) result = orderedDates.Last();
像这样的东西?
List dates = YourListOfStringsHere() ; // list of strings in MM/dd/yyyy form. DateTime desiredDate = new DateTime(2014,2,27) ; DateTime foundDate = dates .Select( x => DateTime.ParseExact(x,"MM/dd/yyyy",CultureInfo.CurrentCulture)) .Where( x => x >= desiredDate.Date ) .Min() ;
为什么你要将日期/时间值存储为字符串超出我的范围。 加载它们时,为什么不转换它们呢? 这样,他们更容易操作,你知道你有干净的数据。 一切都变得简单得多。