0

In my main method I'm constantly checking if given time is equal to current time. But my code seems to fail. This is a windows forms application, not a console application. Not trying to convert string to time span, need some way of checking if two times are equal.

static void Main()
{
    TimeSpan start = TimeSpan.Parse("10:09:00");
    while (true)
    {

        TimeSpan now = DateTime.Now.TimeOfDay;
        if (now == start)
        {
            Debug.WriteLine("Fount at " + now + " " + start);
            Environment.Exit(1);
        }
        Debug.WriteLine("Running Loop at " + now + " "+start);
    }
} 

I tried altering the first line as,

TimeSpan start = TimeSpan.Parse("10:09:00:0000000");

That doesn't seem to work either, Can anybody suggest me a better way?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Nishan
  • 3,644
  • 1
  • 32
  • 41
  • How do you check seconds? – Just code Nov 21 '18 at 04:44
  • @Justcode I'm checking seconds as `00` in `10:09:00` – Nishan Nov 21 '18 at 04:47
  • @Nishin But `DateTime.Now.TimeOfDay` isn't. – ProgrammingLlama Nov 21 '18 at 04:48
  • `DateTime.Now.TimeOfDay` has `00:00:00:0000000` format, that is why i changed my code to `TimeSpan.Parse("10:09:00:0000000")` @John – Nishan Nov 21 '18 at 04:50
  • @Nishin re-read what I said: your code now asks "is 10:09:12:134532" equal to "10:09:00:000000". – ProgrammingLlama Nov 21 '18 at 04:51
  • 1
    You do realize that DateTime and TimeSpan objects have millisecond (or better) precision. It's very possible that the current time (as you calculate it) will never be exactly equal to your `start`. Instead, subtract the two times and check that the result is "close enough" to call them equal – Flydog57 Nov 21 '18 at 04:54
  • Side note: "This is a windows forms application" - this is absolutely not how one writes event-driven program... normally your program should be terminated by Windows due to misbehaving before it gets to wait for more than a minute... – Alexei Levenkov Nov 21 '18 at 06:53

3 Answers3

3

Your problem is probably the milliseconds

You could also use an extension to trim, which will give you a truncated time up to the second

public static class Extensions
{
    public static DateTime TrimMilliseconds(this DateTime dt)
    {
        return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, 0, dt.Kind);
    }
}

Full Demo Here

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
2

Your code does not work since you compare different timespans, and when you add fractional milliseconds it's unlikely they will match.

You can use the following code snippet to compare time:

    TimeSpan start = new TimeSpan(11, 49, 0);
    while (true)
    {
        TimeSpan now = DateTime.Now.TimeOfDay;
        if (Math.Abs((now - start).TotalMilliseconds)<1000)
        {
            Debug.WriteLine("Found at " + now + " " + start);
            Environment.Exit(1);
        }
        Debug.WriteLine("Running Loop at " + now + " " + start);
    }
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Access Denied
  • 8,723
  • 4
  • 42
  • 72
2

Your "start" value is OK, the problem is that TimeOfDay will include much more precision than minutes. You need to somehow truncate the value down to minutes.

This is one such way you could do that:

var now = TimeSpan.FromSeconds(Math.Floor(DateTime.Now.TimeOfDay.TotalSeconds));

TotalSeconds will return a non-integer value (i.e. it will include milliseconds as a fraction), so we take that value, floor it to remove the fraction component, and then convert it back into seconds - now without any values shorter than a second.

Of course you can switch out "Seconds" for Minutes, Hours, etc. as necessary.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86