时间 - 一次差两次

Time - Two times at once difference

我对这段代码有疑问。我会检查两次是否有低于 7 秒的差异。

static void Main(string[] args)
{
    List<DateTime> logDates = new List<DateTime>();

    //Define regex string
    string pattern = @"(?<logDate>(\d){4}-(\d){2}-(\d){2}\s(\d){2}:(\d){2}:(\d){2})";            
    Regex reg = new Regex(pattern);    

    try
    {   // Open the text file using a stream reader.
        using (StreamReader sr = new StreamReader("C:\test.txt"))
        {
            // Read the stream to a string, and write the string to the console.
            String logContent = sr.ReadToEnd();
            Console.WriteLine(logContent);

            //run regex
            MatchCollection matches = reg.Matches(logContent);

            //iterate over matches
            foreach (Match m in matches)
            {
                DateTime logTime = DateTime.Parse(m.Groups["logDate"].Value);
                //logDates.Add(logTime);                        
                Console.WriteLine("TIME:" + logTime.TimeOfDay);
            }
    #if DEBUG
            Console.WriteLine("Press enter to close...");
            Console.ReadLine();
    #endif
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("The file could not be read:");
        Console.WriteLine(e.Message);
    }
}

此代码正确打开 txt 文件 (test.txt),读取日期并打印到控制台。

我的问题是:如何检查两次(一次两次)的差异是否小于 7 秒?

编辑:此外,如果我有一条消息说它可以或不可以,那就太好了。

此致

您可以使用 DateTime.Subtract(DateTime),它会给您一个 TimeSpan 对象,您可以使用它的 属性 TotalSeconds 来找出两个日期之间的差异。

我刚刚 运行 进入这个问题并在 Stack 上找到了一些代码,但我终究找不到原始创建者。我正在发布修改后的代码,但如果有人可以识别原作者,请告诉我,我会确保注明出处。使用下面的代码,您可以输入两个日期并获得一些比较它们的选项。

using System;

namespace BFSShared
{
    /// <summary>
    /// </summary>
    public struct DateTimeSpan
    {
        private readonly int years;
        private readonly int months;
        private readonly int days;
        private readonly int hours;
        private readonly int minutes;
        private readonly int seconds;
        private readonly int milliseconds;

        /// <summary>
        /// Initializes a new instance of the <see cref="DateTimeSpan"/> struct.
        /// </summary>
        /// <param name="years">The years.</param>
        /// <param name="months">The months.</param>
        /// <param name="days">The days.</param>
        /// <param name="hours">The hours.</param>
        /// <param name="minutes">The minutes.</param>
        /// <param name="seconds">The seconds.</param>
        /// <param name="milliseconds">The milliseconds.</param>
        public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
        {
            this.years = years;
            this.months = months;
            this.days = days;
            this.hours = hours;
            this.minutes = minutes;
            this.seconds = seconds;
            this.milliseconds = milliseconds;
        }

        /// <summary>
        /// Gets the years.
        /// </summary>
        /// <value>
        /// The years.
        /// </value>
        public int Years { get { return years; } }
        /// <summary>
        /// Gets the months.
        /// </summary>
        /// <value>
        /// The months.
        /// </value>
        public int Months { get { return months; } }
        /// <summary>
        /// Gets the days.
        /// </summary>
        /// <value>
        /// The days.
        /// </value>
        public int Days { get { return days; } }
        /// <summary>
        /// Gets the hours.
        /// </summary>
        /// <value>
        /// The hours.
        /// </value>
        public int Hours { get { return hours; } }
        /// <summary>
        /// Gets the minutes.
        /// </summary>
        /// <value>
        /// The minutes.
        /// </value>
        public int Minutes { get { return minutes; } }
        /// <summary>
        /// Gets the seconds.
        /// </summary>
        /// <value>
        /// The seconds.
        /// </value>
        public int Seconds { get { return seconds; } }
        /// <summary>
        /// Gets the milliseconds.
        /// </summary>
        /// <value>
        /// The milliseconds.
        /// </value>
        public int Milliseconds { get { return milliseconds; } }

        private enum Phase { Years, Months, Days, Done }

        /// <summary>
        /// Compares the dates.
        /// </summary>
        /// <param name="date1">The date1.</param>
        /// <param name="date2">The date2.</param>
        /// <returns></returns>
        public static DateTimeSpan CompareDates(DateTime date1, DateTime date2)
        {
            if (date2 < date1)
            {
                var sub = date1;
                date1 = date2;
                date2 = sub;
            }

            var current = date1;
            var years = 0;
            var months = 0;
            var days = 0;

            var phase = Phase.Years;
            var span = new DateTimeSpan();
            var officialDay = current.Day;

            while (phase != Phase.Done)
            {
                switch (phase)
                {
                    case Phase.Years:
                        if (current.AddYears(years + 1) > date2)
                        {
                            phase = Phase.Months;
                            current = current.AddYears(years);
                        }
                        else
                        {
                            years++;
                        }
                        break;
                    case Phase.Months:
                        if (current.AddMonths(months + 1) > date2)
                        {
                            phase = Phase.Days;
                            current = current.AddMonths(months);
                            if (current.Day < officialDay && officialDay <= DateTime.DaysInMonth(current.Year, current.Month))
                                current = current.AddDays(officialDay - current.Day);
                        }
                        else
                        {
                            months++;
                        }
                        break;
                    case Phase.Days:
                        if (current.AddDays(days + 1) > date2)
                        {
                            current = current.AddDays(days);
                            var timespan = date2 - current;
                            span = new DateTimeSpan(years, months, days, timespan.Hours, timespan.Minutes, timespan.Seconds, timespan.Milliseconds);
                            phase = Phase.Done;
                        }
                        else
                        {
                            days++;
                        }
                        break;
                    case Phase.Done:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            return span;
        }
    }
}

原始代码可以在这里找到, Difference in months between two dateshttps://whosebug.com/users/189950/kirk-woll

撰写

这里有一个使用DateTime.Subtract

的例子
DateTime datetime1 = DateTime.Now;
DateTime datetime2 = DateTime.Now;

if (datetime2.Subtract(datetime1).TotalSeconds < 7)
{
    Console.WriteLine("Less than 7 seconds");
}

不确定其他答案是否为您解决了这个问题。

更新代码以比较滚动列表中的 2 个日期。 所以检查 A[1]-A[0] 低于 7 秒或 A[2]-A[1] 低于 7 秒

//mock of your list collection
  List<DateTime> dates = new List<DateTime>()
  {
      {DateTime.Now},
      {DateTime.Now.AddSeconds(8)},
      {DateTime.Now.AddSeconds(18)},
      {DateTime.Now.AddSeconds(28)},
      {DateTime.Now.AddSeconds(30)},
   };

   //tempoary store the previous 3 dates
   List<DateTime> dates2 = new List<DateTime>();

   foreach (var item in dates)
   {
       dates2.Add(item);
       if (dates2.Count > 2)
       {
           //Check if either dates2[0] & dates2[1] and dates2[1] and dates[2] are 7 seconds apart
           if (dates2.Zip(dates2.Skip(1), (x, y) => y.Subtract(x))
               .Any(x => x.TotalSeconds < 7))
           {
               Console.WriteLine("OK");
           }

          //remove the first element so only 3 dates in the temporary list
          dates2.RemoveAt(0);
       }
}

根据你的问题,我假设你正在尝试检查两个 DateTime 之间的差异是否小于 7 秒。这是我希望能有所帮助的东西。

    static void Main(string[] args)
    {
        TimeSpan span = new TimeSpan(0, 0, 0, 7, 0);

        //Your array of DateTimes
        DateTime[] dateTimes = new DateTime[]
        {
            new DateTime(2017, 04, 18, 0, 0, 0),
            new DateTime(2017, 04, 18, 0, 0, 7),
            new DateTime(2017, 04, 18, 0, 0, 15),
            new DateTime(2017, 04, 18, 0, 0, 21),
        };

        //Check through whole array of DateTimes, in sequence
        for (int i = 0; i < dateTimes.Count() - 1; i++)
        {
            if (dateTimes[i + 1] - dateTimes[i] <= span)
            {
                Console.WriteLine("OK");
            }
            else
            {
                Console.WriteLine("NOT OK");
            }
        }
        //Output of this example:
        //OK
        //NOT OK
        //OK

您需要比较所有日志日期。如果您先订购商品,那么它将是 "easier",然后找到相差小于 7 秒的第一个日期和 return 它们以及介于两者之间的其余商品。

var logDates = new List<DateTime>(); // loaded from file

var orderedLogDates = logDates.OrderBy(logDate => logDate).ToList();
var lowIndex = 0;
var upperIndex = orderedLogDates.Count - 1;
while (lowIndex < upperIndex)
{
    var diff = (orderedLogDates[upperIndex] - orderedLogDates[lowIndex]).TotalSeconds;
    if (diff < 7)
    {
        // Here we can return all items between lower and upper indexes
        var amountToReturn = upperIndex - lowIndex;
        return orderedLogDates.GetRange(lowIndex, amountToReturn);
    }
    lowIndex++;
    upperIndex--;
}
return new List<DateTime>(); // empty list if not found

在循环中,您可以检查每个日期与已读日期,并将它们保存在列表中。

foreach (Match m in matches)
{
    DateTime logTime = DateTime.Parse(m.Groups["logDate"].Value);
    bool alreadyExistsLessThanSevenSeconds = 
        logDates.Any(dateTime => Math.Abs((dateTime - currentDateTime).TotalSeconds) <= 7);

    if (alreadyExistsLessThanSevenSeconds)
    {
        // Exists within the seven seconds range
    }
    {
        // Doesnt exists within the seven seconds range
    }
    logDates.Add(logTime);

    Console.WriteLine("TIME:" + logTime.TimeOfDay);
}

如果将所有 DateTimes 放入一个集合中,则可以使用此 LINQ 查找与另一个时间相差 7 秒以内的那些。

它首先确保所有时间都是有序的,然后检查列表中的前一个时间,看它们的差异是否小于 7 秒。

这是一个例子...

DateTime d1 = DateTime.Now;
DateTime d2 = DateTime.Now.AddSeconds(5);
DateTime d3 = DateTime.Now.AddSeconds(15);
DateTime d4 = DateTime.Now.AddSeconds(30);
DateTime d5 = DateTime.Now.AddSeconds(32);

List<DateTime> times = new List<DateTime>() { d1, d2, d3, d4, d5 };

var withinSeven = times.OrderBy(t => t)
    .Where((t, i) =>
        i > 0 && t.Subtract(times[i - 1]).Seconds < 7)
    .ToList();

foreach (var time in withinSeven)
    Console.WriteLine(time);