我有一些日期当前存储为字符串列表。
例如:
List<string> dates = new List<string>();
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类型,但我无法找出找到这样日期的逻辑。
答案 0 :(得分:8)
List<string> dates = new List<string>();
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,你可以去看看并做二分搜索。
答案 1 :(得分:3)
以下是使用二进制搜索的解决方案。
您需要有一个DateTime
的列表,对此毫无疑问。没有必要将它们保留为string
,如果必须,将它们解析到列表的路上。您可以使用LINQ转换列表中的所有元素,但这是您能够相互比较日期的唯一方法。
查看BinarySearch
的页面,了解我在返回值上使用按位运算符的原因。
//build list of random dates
Random r = new Random();
var dates = new List<DateTime>();
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];
}
答案 2 :(得分:2)
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();
答案 3 :(得分:2)
这样的东西?
List<string> 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()
;
为什么你要将日期/时间值存储为字符串超出我的范围。加载它们时,为什么不转换它们呢?这样,他们更容易操作,你知道你有干净的数据。一切都变得简单了。