Таймер обратного отсчета пропускает время в C#

У меня есть это на С#

private void counter_Tick(object sender, EventArgs e)
    {
        Time.Text = String.Format("{0:000}", Hour) + ":" + String.Format("{0:00}", Minute) + ":" + String.Format("{0:00}", Second);
        if (Second != 00)
        {
            Second = Second - 1;
        }
        else if (Minute != 00)
        {
            Minute = Minute - 1;
            Second = 59;
        }
        else if (Hour != 00)
        {
            Hour = Hour - 1;
            Minute = 59;
        }
        else
        {
            counter.Stop();
            Time.ForeColor = Color.Red;
        }
    }

Что действительно работает, но когда он доходит до минус часа, чтобы добавить к минутам, он переходит с 00 минут на 58 минут вместо 59.

EG.

From: 001:00:00
To:   000:58:59

И есть ли лучший способ сделать таймер обратного отсчета, который что-то делает, когда достигает 000:00:00???


person Adam Coulson    schedule 15.05.2012    source источник
comment
Я бы не использовал таймер для этого или не таким образом. Я бы использовал DateTime для этого.   -  person Milan Halada    schedule 15.05.2012


Ответы (4)


Хорошо, давайте посмотрим, что произойдет, когда время будет 10:00:00.

  1. Вычтите один час: 09:00:00.
  2. Установите минуты на 59: 09:59:00.

Если вы заметили, что время отстает на одну минуту (10:00:00 - 09:59:00 = 00:01:00). Решение состоит в том, чтобы также установить секунды на 59. Итак, теперь наш код.

// ...
else if (Hour != 00)
{
    Hour = Hour - 1;
    Minute = 59;
    Second = 59;
}
// ...
person Community    schedule 15.05.2012

Вы можете использовать стандартные классы .Net для вычитания времени:

private TimeSpan timeSpan;
private TimeSpan oneSecond = new TimeSpan(0, 0, 1);

private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    Time.Text = timeSpan.ToString();

    if (timeSpan == TimeSpan.Zero)
    {
        Time.ForeColor = Color.Red;
        timer.Stop();
        return;
    }

    timeSpan -= oneSecond;
}

Инициализируйте промежуток времени при запуске таймера (я использовал System.Timers.Timer):

timeSpan = new TimeSpan(1, 0, 0);
Timer timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
person Sergey Berezovskiy    schedule 15.05.2012

Вам также необходимо установить Second на 59. В противном случае, как только таймер снова тикает, он немедленно переключается на else if (Minute != 00) и уменьшает Minute (которое уже равно 59) на единицу.

person Botz3000    schedule 15.05.2012

person    schedule
comment
Промежутки времени были бы лучшим выбором, поскольку вас не интересует часть даты. final.addSeconds(-1).ToString() будет лучше, чем (final-start) 3 раза, поскольку это может означать, что вы пропускаете интервалы, поскольку время всегда идет вперед. - person Simon Halsey; 15.05.2012
comment
Да, это правда, но все же лучше, чем оригинальное решение, я считаю - person Milan Halada; 15.05.2012
comment
На самом деле это не так. Только что посмотрел еще раз, и каждый тик счетчика будет просто выводить 1:00:00, так как при каждом тике счетчика ничего не уменьшается. ваш окончательный код никогда не будет достигнут, поскольку окончательный никогда не может равняться началу. - person Simon Halsey; 15.05.2012
comment
:D Упс, правда, не заметил, починил - person Milan Halada; 15.05.2012