如何在遍历列表时比较 DateTime 对象?

Posted

技术标签:

【中文标题】如何在遍历列表时比较 DateTime 对象?【英文标题】:How to compare DateTime Objects while looping through a list? 【发布时间】:2012-06-11 08:25:03 【问题描述】:

我正在尝试遍历包含两个字段的列表 (csv);姓名和日期。列表中有各种重复的名称和各种日期。我试图推断列表中的每个名称,其中有多个相同名称的实例,对应的日期是最新的。

通过查看另一个答案,我意识到我需要使用 DateTime.Compare 方法,这很好,但我的问题是确定哪个日期更晚。一旦我知道这一点,我需要生成一个具有唯一名称和与之相关的最新日期的文件。

这是我成为新手的第一个问题。

编辑:

最初,我认为将 LatestDate 对象设置为不会显示在我的文件中的日期是“可以的”,因此将文件中的任何较晚日期设为 LatestDate。

这是我目前的编码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace flybe_overwriter

class Program

    static DateTime currentDate;
    static DateTime latestDate = new DateTime(1000,1,1);
    static HashSet<string> uniqueNames = new HashSet<string>();

    static string indexpath = @"e:\flybe test\indexing.csv";
    static string[] indexlist = File.ReadAllLines(indexpath);
    static StreamWriter outputfile = new StreamWriter(@"e:\flybe test\match.csv");

    static void Main(string[] args)
    

        foreach (string entry in indexlist)
        

            uniqueNames.Add(entry.Split(',')[0]);

        

        HashSet<string>.Enumerator fenum = new HashSet<string>.Enumerator();
        fenum = uniqueNames.GetEnumerator();

        while (fenum.MoveNext())
        
            string currentName = fenum.Current;


            foreach (string line in indexlist)
            
                currentDate = new DateTime(Convert.ToInt32(line.Split(',')[1].Substring(4, 4)), 
                                           Convert.ToInt32(line.Split(',')[1].Substring(2, 2)), 
                                           Convert.ToInt32(line.Split(',')[1].Substring(0, 2)));

                if (currentName == line.Split(',')[0])
                 
                    if(DateTime.Compare(latestDate.Date, currentDate.Date) < 1)
                    
                      //  Console.WriteLine(currentName + " " + latestDate.ToShortDateString() + " is earlier than " + currentDate.ToShortDateString());
                    
                    else if (DateTime.Compare(latestDate.Date, currentDate.Date) > 1)
                    
                     //   Console.WriteLine(currentName + " " + latestDate.ToShortDateString() + " is later than " + currentDate.ToShortDateString());
                    
                    else if (DateTime.Compare(latestDate.Date, currentDate.Date) == 0)
                    
                     // Console.WriteLine(currentName + " " + latestDate.ToShortDateString() + " is the same as " + currentDate.ToShortDateString());
                    

                
            

        


    

任何帮助表示赞赏。 谢谢。

【问题讨论】:

“我意识到,通过查看另一个答案,我需要使用 DateTime.Compare 方法“嗯......哪个答案?你有链接吗?为什么不能只使用dt1.Date &lt; dt2.Date?但我认为使用 LINQ 重写会更好。 我不确定您在寻找什么。您是在说“我的问题是确定哪个日期更晚”,但您的代码已经解决了这个问题。您能否更新您的问题文本以使实际问题/问题更加明显? 仅供参考; StreamWriter 最好放在 using 语句中,以确保在不再需要时将其从内存中删除。 link 但是如果你的目的只是为了推断出所有的重复名称,你为什么要写那么多代码呢?它可以做得比这更简单 @MarkByers I found this answer on ***. 【参考方案1】:

合而为一,在您的 Datetimes 上使用 Max() 函数,而不是进行自己的测试。

var result = indexList
        //"transform" your initial list of strings into an IEnumerable of splitted strings (string[])
        .Select(list => list.Split(','))
        //in this new List of string[], select the first part in text, select and Convert the second part in DateTime. 
        //We now have an IEnumerable of anonymous objects, composed of a string and a DateTime Property
        .Select(splittedList => new
                                    
                                        text = splittedList[0],
                                        date = new DateTime(Convert.ToInt32(splittedList[1].Substring(4, 4)),
                                                            Convert.ToInt32(splittedList[1].Substring(2, 2)),
                                                            Convert.ToInt32(splittedList[1].Substring(0, 2)))
                                    )
        //group that new List by the text Property (one "entry" for each distinct "text"). 
        //GroupBy creates an IGrouping<out TKey, out TElement>, kind of special dictionary, with an IEnumerable<TResult> as "value" part 
        //(here an IEnumerable of our anonymous object)
        .GroupBy(textDateTimeList => textDateTimeList.text)
         //from this grouping, take the "key" (which is the "distinct text", and in the IEnumerable<anonymousObject>, take the Max Date. 
         //We now have a new List of anonymous object, with a string Property and a DateTime Property
        .Select(group => new
                             
                                 stringField = group.Key,
                                 maxDateField = group.Max(dateField => dateField.date)
                             );

【讨论】:

好的。将不得不看看这个,看看我得到了什么结果。谢谢。 所以。我已经实现了这个编码并且它工作得非常好......还没有关于它是如何工作的线索,因为我以前从未见过这样的脚本(地狱,我现在真的觉得自己像个新手......)谢谢再次。 好吧,那么欢迎使用 linq,如果有帮助,我会尝试发表评论……但需要更多阅读。 感谢 cmets 并抽出宝贵的时间来写作。比我尝试的要容易得多! 没有问题。如果您想“关闭”您的问题,可以将答案标记为已接受meta.stackexchange.com/questions/5234/…

以上是关于如何在遍历列表时比较 DateTime 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何在排序对象列表时解决自定义比较器的意外行为?

Javascript:如何遍历模型中的对象列表

如何遍历存储在数组列表中的对象[重复]

如何遍历没有 id 属性的对象列表

如何遍历对象列表并将特定值合并到一个大列表[关闭]

如何对对象中包含的列表进行排序