我有一个时间值列表,格式为“09.00 AM,12.00 PM,03.00 PM”等等。小时称之为ListTimes .. 我有一个时间值(testTimeValue)与我传递给函数的格式“xx.xx AM / PM”相同。 我希望函数将此'testTimeValue'与ListTimes中的每个项进行比较,并返回最接近它的时间。例如:在上面的场景中,如果我将01.00 PM传递给该函数,它应该返回03.00 PM。
foreach (string item in listItems)
{
//I need to consider the time formats in AM and PM and do a
//proper comparison and return the closest in original format.
}
return closestTimeValue;
答案 0 :(得分:5)
每次都要运行DateTime.ParseExact
List<string> listTimes = new List<string>() { "09.00 AM", "12.00 PM", "03.00 PM" };
string testTimeString = "01.00 PM";
DateTime testTime = DateTime.ParseExact(testTimeString, "hh.mm tt", CultureInfo.InvariantCulture);
DateTime closestTime = DateTime.MinValue;
TimeSpan closestDifference = TimeSpan.MaxValue;
foreach (string item in listTimes)
{
DateTime itemTime = DateTime.ParseExact(item, "hh.mm tt", CultureInfo.InvariantCulture);
TimeSpan itemDifference = (itemTime - testTime).Duration();
if (itemDifference < closestDifference)
{
closestTime = itemTime;
closestDifference = itemDifference;
}
}
return closestTime.ToString("hh.mm tt");
答案 1 :(得分:1)
首先我相信数据类型是DateTime
List<DateTime> dates = new List<DateTime>();
dates.Add(DateTime.Parse("9/11/2001 1:00 PM"));
dates.Add(DateTime.Parse("9/11/2001 10:00 AM"));
dates.Add(DateTime.Parse("9/11/1002 3:00 PM"));
DateTime dateComp = DateTime.Parse("9/11/2001 11:00 AM");
DateTime? dateClosest = null;
foreach (DateTime dt in dates)
{
if (dateClosest == null) dateClosest = dt;
else
{
if( (dateComp.Subtract(dt).TotalMilliseconds) <
dateComp.Subtract((DateTime)dateClosest).TotalMilliseconds)
{
dateClosest = dt;
}
}
}
答案 2 :(得分:1)
有趣的问题:)我写了这个小测试程序来试试。如果您认为有意义,您应该能够根据自己的需求进行调整。基本上,从基准日期时间开始,在相同的24小时内生成一个随机的“测试”,然后随机生成一堆额外的时间,然后查看哪一个与测试值具有最小的差异(在您的情况下将是是一个被比较的人。
List<DateTime> times = new List<DateTime>();
Random rnd = new Random();
int hourCount = (24 * 60) - 1;
DateTime dtBase = DateTime.Parse("01/01/2012 12:00 AM");
DateTime dtTest = dtBase.AddMinutes(rnd.Next(0, hourCount));
Console.WriteLine("Base: " + dtBase.ToString());
Console.WriteLine("Test: " + dtTest.ToString());
Console.WriteLine();
for (int i = 0; i < 24; i++) {
times.Add(dtBase.AddMinutes(rnd.Next(0, hourCount)));
}
times.Sort();
TimeSpan lastSpan = TimeSpan.MaxValue;
DateTime dtMatch = DateTime.Now;
foreach (DateTime dt in times) {
Console.Write(" " + dt.ToString());
var diff = (dtTest - dt).Duration();
if (diff < lastSpan) {
lastSpan = diff;
dtMatch = dt;
}
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("Closest match to {0:hh:mm tt} => {1:hh:mm tt} ({2})", dtTest, dtMatch, lastSpan);
示例输出运行:
Base: 1/1/2012 12:00:00 AM
Test: 1/1/2012 3:28:00 AM
1/1/2012 1:03:00 AM
1/1/2012 2:51:00 AM
1/1/2012 2:52:00 AM
1/1/2012 3:22:00 AM
1/1/2012 4:30:00 AM
1/1/2012 4:36:00 AM
1/1/2012 5:50:00 AM
1/1/2012 5:55:00 AM
1/1/2012 6:50:00 AM
1/1/2012 7:05:00 AM
1/1/2012 7:17:00 AM
1/1/2012 8:53:00 AM
1/1/2012 9:25:00 AM
1/1/2012 11:59:00 AM
1/1/2012 12:22:00 PM
1/1/2012 12:51:00 PM
1/1/2012 2:04:00 PM
1/1/2012 3:01:00 PM
1/1/2012 3:26:00 PM
1/1/2012 4:19:00 PM
1/1/2012 6:15:00 PM
1/1/2012 11:02:00 PM
1/1/2012 11:28:00 PM
1/1/2012 11:50:00 PM
Closest match to 03:28 AM => 03:22 AM (00:06:00)
因此,您案例中的实际功能如下所示:
DateTime GetClosestTime(DateTime testTimeValue, List<DateTime> listItems) {
TimeSpan lastSpan = TimeSpan.MaxValue;
DateTime dtMatch = DateTime.Now;
foreach (DateTime dt in listItems) {
var diff = (testTimeValue - dt).Duration();
if (diff < lastSpan) {
lastSpan = diff;
dtMatch = dt;
}
}
return dtMatch;
}
假设您有时间与其他位置进行比较,您可以将其重写为省略testTimeValue
参数。
希望这有帮助!
答案 3 :(得分:1)
这是一个Linq版本,虽然这比Guvante的答案要慢:
List<string> ListTimes = new List<string>() { "09.00 AM", "12.00 PM", "03.00 PM" };
string testTimeString = "01.00 PM";
DateTime testTime = DateTime.ParseExact(testTimeString, "hh.mm tt", CultureInfo.InvariantCulture);
return ListTimes
.Select(x => new
{
Time = x,
Difference = (DateTime.ParseExact(x, "hh.mm tt", CultureInfo.InvariantCulture) - testTime).Duration()
})
.OrderBy(x => x.Difference)
.First().Time;
答案 4 :(得分:1)
你可以自己写。解决这些任务甚至很有趣......有时候))
static void Main(string[] args)
{
var listTimes = new string[] {"09.00 AM", "12.00 PM", "03.00 AM"};
const string testTimeValue = "02.00 PM";
Console.WriteLine(CompareFunction(listTimes, testTimeValue));
}
public static string CompareFunction(IEnumerable<string> listTimes, string testTimeValue)
{
double minDiff = double.MaxValue;
string result = string.Empty;
foreach(string listTime in listTimes)
{
double difference = GetDifference(listTime, testTimeValue);
if(difference < minDiff)
{
minDiff = difference;
result = listTime;
}
}
return result;
}
private static double GetDifference(string time1, string time2)
{
return Math.Abs(ConvertStringTime(time1).TotalMinutes - ConvertStringTime(time2).TotalMinutes);
}
private static TimeSpan ConvertStringTime(string time)
{
Regex validationRegex = new Regex(@"\d\d.\d\d AM|PM");
if(!validationRegex.IsMatch(time)) throw new FormatException("Input time string was not in correct format");
Regex hoursRegex = new Regex(@"\d\d.");
Regex minutesRegex = new Regex(@".\d\d");
bool postMeridiem = time.Contains("PM");
string hstring = hoursRegex.Match(time).ToString().Replace(".", string.Empty);
string mstring = minutesRegex.Match(time).ToString().Replace(".", string.Empty);
double h = postMeridiem ? double.Parse(hstring) + 12 : double.Parse(hstring);
double m = double.Parse(mstring);
return new TimeSpan(0, (int)h, (int)m, 0);
}