-2

I have a doubt about this code. I would check if two times have a difference lower than 7 seconds.

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);
    }
}

This code open corretly the txt file (test.txt), read the date and print to console.

MY QUESTION IS: How can check if two times (TWO AT ONCE) have a difference lower than 7 seconds?

EDIT: Furthermore would be good, if i have a message to say it's OK or NOT OK.

Regards

Mighty Badaboom
  • 6,067
  • 5
  • 34
  • 51
nonac
  • 35
  • 7

7 Answers7

1

Based on your question I am assuming that you're trying to check that the difference between two DateTime's are lower than 7 seconds. Here is something I hope may help.

    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
Oli
  • 314
  • 3
  • 13
  • Thank you for your reply, but it would have a solution to check (two at once) two times if they are lower than 7 second. So i try to describe well the context. I would have an array where A[0] is a time A[1] is another time. I check A[1]-A[0] lower than 7 second --> OK. A[2]-A[1] lower than 7 second --> OK.. Bla bla bla.. Regards – nonac Apr 18 '17 at 13:56
  • @nonac I think I understand. Please see my updated code. – Oli Apr 18 '17 at 14:06
  • thank you for your reply. I don't undestrand new DateTime structure, why i use 0,7,15,21 ? i would have only 7 seconds difference. Furthemore i would have only one Console.WriteLine("OK") to say that all times are lower than 7 second from yours previous – nonac Apr 18 '17 at 14:17
  • The structure is just to show an example of how this would work. You would load your DateTimes into an array, then the for loop would be used to check through the array. I've added what you could expect outputted as a result of my example. – Oli Apr 18 '17 at 14:21
0

You can use DateTime.Subtract(DateTime) which will give you a TimeSpan object, and you can use its property TotalSeconds to figure out the difference between the two dates.

AD.Net
  • 13,352
  • 2
  • 28
  • 47
0

I just ran into this issue and found some code here on Stack, but for the life of me cannot find the original creator. I am posting modified code, but if anyone can identify the original author, please let me know and I will make sure to credit them. With the code below, you can enter two dates and get a few options of comparing them.

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;
        }
    }
}

Original code can be found here, Difference in months between two dates Was written by https://stackoverflow.com/users/189950/kirk-woll

Community
  • 1
  • 1
Kevin B Burns
  • 1,032
  • 9
  • 24
  • Thank you for your reply, but it would have a solution to check (two at once) two times if they are lower than 7 second. So i try to describe well the context. I would have an array where A[0] is a time A[1] is another time. I check A[1]-A[0] lower than 7 second --> OK. A[2]-A[1] lower than 7 second --> OK.. Bla bla bla.. Regards – nonac Apr 18 '17 at 13:56
0

Here is an an example of using DateTime.Subtract

DateTime datetime1 = DateTime.Now;
DateTime datetime2 = DateTime.Now;

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

Not sure if the other answers solved this for you.

Updated code to compare a 2 dates in a rolling list. So checks A[1]-A[0] lower than 7 second or A[2]-A[1] lower than 7 second

//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);
       }
}
Scrobi
  • 1,215
  • 10
  • 13
0

You need compare all log dates. It will be "easier" if you order items first, then find first dates which difference is less then 7 seconds and return them and rest of items between.

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
Fabio
  • 31,528
  • 4
  • 33
  • 72
  • Thank you for your reply, my time are order yet when i read the txt file. but it would have a solution to check (two at once) two times if they are lower than 7 second. So i try to describe well the context. I would have an array where A[0] is a time A[1] is another time. I check A[1]-A[0] lower than 7 second --> OK. A[2]-A[1] lower than 7 second --> OK.. Bla bla bla.. Regards – nonac Apr 18 '17 at 14:01
0

In the loop you can check each date with the already read dates, and keep them in a list.

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);
}
Ofir Winegarten
  • 9,215
  • 2
  • 21
  • 27
0

If you put all of your DateTimes into a collection you can then use this LINQ to find the ones that are within 7 seconds of another time.

It first makes sure all of the times are ordered, then it checks the previous time in the list and sees if their difference is less than 7 seconds.

Here is an example...

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);
Blake Thingstad
  • 1,639
  • 2
  • 12
  • 19