Расчет секундомера (конвертировать 00:00) в 00:00 - PullRequest
0 голосов
/ 23 февраля 2020

Я сталкиваюсь с небольшой проблемой, это простой секундомер, но я хочу сохранять последнюю дату каждый раз, когда программа закрывает ее или нажимает «Стоп», чтобы вычислять время для каждого нажатия кнопки «Пуск» до тех пор, пока не остановится что-то вроде времени изготовления.

В качестве примера: если я нажал кнопку запуска сегодня на 5 секунд, то закрыл программу, хочу сохранить 5 секунд.

Затем, когда я снова открываю программу, она начинается с нуля, но делает суммирование 5 секунд.

  • Второй раз = первый раз + второй раз
  • Второй раз = 05 + 000 ..

Если я нажал кнопку Пуск для 8 секунд, это станет:

  • второй раз = 8 + 5 = 13

Если я закрою программу и снова открою ее и нажму кнопку Пуск в течение 7 секунд

  • во второй раз = 7 + 13 = 20 секунд

но все время я конвертирую его в ("ЧЧ: мм: сс")

Так и получилось

00:00:00 converts to 2/23/2020 12:00:00 AM.

Я хочу преобразовать его в 00:00:00 без какой-либо даты (месяц, год ...)

B потому что, когда я делаю суммирование, это дает мне неправильный номер.

System.Timers.Timer t;
int D, H, m, s;
CultureInfo enUS = new CultureInfo("en-US");
DateTime Drawing;
DateTime Rent;
long Machine_time;

public Form1()
{
        InitializeComponent();
        Rent = Properties.Settings.Default.Drawing_Time;
}

private void Start_Click(object sender, EventArgs e)
{
        t.Start();
}

private void Stop_Click(object sender, EventArgs e)
{
        t.Stop();

        try
        {
            // Drawing = DateTime.ParseExact(textBox1.Text, @"HH:mm:ss", CultureInfo.InvariantCulture);
            Drawing = DateTime.Parse(textBox1.Text);
          //  Drawing = DateTime.Now.ToString( @"HH:mm:ss");
            Console.WriteLine("{0} converts to {1}.", textBox1.Text, Drawing.ToString());
        }
        catch (FormatException)
        {
            Console.WriteLine("{0} is not in the correct format.", textBox1.Text);
        }

        Properties.Settings.Default.Drawing_Time = Drawing;

        long elapsedTicks = Drawing.Ticks ;
        Machine_time = elapsedTicks + Machine_time;
        TimeSpan elapsedSpan = new TimeSpan(Machine_time);
        MessageBox.Show(Drawing.ToString());

        string message = elapsedSpan.ToString();
        MessageBox.Show(message);

        saveSettings();
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
       Properties.Settings.Default.Machine_Time = Machine_Time ;

        saveSettings();
        t.Stop();
        Application.DoEvents();
    }

    public void saveSettings()
    {
        try
        {
            Properties.Settings.Default.Save();
            MessageBox.Show("Saved Settings");
        }
        catch (Exception e)
        {
            MessageBox.Show("Save Settings: " + e);
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        t = new System.Timers.Timer();
        t.Interval = 1000;
        t.Elapsed += onTimeEvent;
    }

    private void onTimeEvent(object sender, System.Timers.ElapsedEventArgs e)
    {
        Invoke(new Action(() =>
        { 
            s += 1;

            if (s == 60)
            {
                s = 0;
                m += 1;
            }

            if (m == 60)
            {
                m = 0;
                H += 1;
            }

            if (H == 24)
            {
                H = 0;
                D += 1;
            }

            labelResult.Text = string.Format("{0}:{1}:{2}:{3}", D.ToString().PadLeft(2, '0'), H.ToString().PadLeft(2, '0'), m.ToString().PadLeft(2, '0'), s.ToString().PadLeft(2, '0'));
            textBox1.Text= string.Format("{0}:{1}:{2}",  H.ToString().PadLeft(2, '0'), m.ToString().PadLeft(2, '0'), s.ToString().PadLeft(2, '0'));
        }));
}

Ответы [ 3 ]

2 голосов
/ 24 февраля 2020

Я вижу, вы используете DateTime для хранения "накопленного времени" или того, сколько времени прошло. Не используйте DateTime для этого. DateTime, как следует из названия, предназначен для хранения частей DATE и TIME, а также когда вы думаете, «сколько времени прошло с 5 дней go?» Вы не отвечаете на такой вопрос "5 мая". Вам нужно то, что не заботится о календарных датах. Просто само время.

То, что вы хотите использовать, это TimeSpan, это интервал времени без дат. Этот тип данных просто описывает, сколько времени прошло. Вы не найдете там «13 февраля», поскольку месячные дни используются для описания временных, а не временных интервалов. В TimeSpan временной интервал описывается как секунды / минуты / часы / дни, и это все. Продолжительность года / месяца варьируется в зависимости от разных вещей, поэтому это не очень хорошая единица измерения для временного интервала. Можно утверждать, что «неделя» всегда длится 7 дней, хорошо, мы могли бы использовать и ее, но у TimeSpan нет недель. day - это последняя единица в TimeSpan.

Поиграйте немного с TimeSpan, и, скорее всего, вы решите все самостоятельно и получите более увлекательное кодирование.

О, вы также можете заметить, что вы можете вычесть DateTime. Datetime минус другое datetime возвращает значение TimeSpan. Handy.

1 голос
/ 24 февраля 2020

Ваша попытка - довольно сложная программа, кажется, для того, что она есть .. Было бы проще просто использовать datetime:

private DateTime _startTime = DateTime.MinValue;

public Form1()
{
        InitializeComponent();
}

private void Start_Click(object sender, EventArgs e)
{
        _startTime = DateTime.UtcNow;
}

private void Stop_Click(object sender, EventArgs e)
{
        StopStopwatch(true);
}

private void StopStopwatch(bool showErrorMessages)
{
        if(_startTime > DateTime.MinValue)
            Properties.Settings.Default.ElapsedTotalSeconds += (DateTime.UtcNow - _startTIme).TotalSeconds;
        else if(showErrormessages)
            MessageBox.Show("Stopwatch isn't running");

        _startTIme = DateTime.MinValue; //if minvalue it means the stopwatch isn't running
}

private void Reset_Click(object sender, EventArgs e)
{
        Properties.Settings.Default.ElapsedTotalSeconds = 0;
}        


private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
        StopStopwatch(false);
        Properties.Settings.Default.Save();
}


//if you want a visual feedback the timer is running, have a timer that you start and stop with the click events, and update a label in its tick event
private void Timer_Tick(...) //its a windows forms timer, not a system timers timer
{
        if(_startTIme > DateTime.MinValue){

          TimeSpan ts = TimeSpan.FromSeconds(Properties.Settings.Default.ElapsedTotalSeconds);

          ts += (DateTime.UtcNow - _startTime);

          Label1.Text = ts.ToString();

        }
}

Это все, что вам нужно для управления гайками и болтами этого :

  • Запишите время, когда кто-то нажмет старт. результирующего временного интервала. Пометьте секундомер как не работающий, поэтому, если он снова нажмет «Стоп», он не будет добавлен снова

  • Сохранение этих секунд в сохранении настроек (примечание: должна быть настройка пользовательской области, должна быть двойного типа)

  • Если они выйдут из приложения во время работы таймера, остановите таймер, добавьте секунды, сохраните настройки, закройте приложение

Обеспечить механизм сброса.

Если вам нужна какая-то визуальная обратная связь, по которой работает таймер, см. нижнюю часть кода - это таймер, который будет периодически обновлять метку с текущим общим временем, полученным из TimeSpan на основе значение настроек, а также интервал времени, основанный на разнице между нажатием кнопки «Пуск» и «сейчас». Метка будет обновляться каждый раз, когда таймер тикает. Если вы хотите, чтобы синица обновлялась 10 раз в секунду, установите интервал таймера 100 мс

0 голосов
/ 24 февраля 2020

Спасибо за руководство, да я просто заменяю DateTime на TimeSpane, но да, у него есть некоторые ограничения на неделю, но я могу с этим разобраться. еще раз спасибо

и этот код модификации

  private void Stop_Click(object sender, EventArgs e)
    {
        t.Stop();
          try
        {
            Drawing_time =  TimeSpan.Parse (labelResult.Text);
            Console.WriteLine("{0} converts to {1}.", labelResult.Text, Drawing_time.ToString());
        }
        catch (FormatException)
        {
            Console.WriteLine("{0} is not in the correct format.", labelResult.Text);
        }
         Machine_time = Drawing_time + Machine_time;
        Properties.Settings.Default.Machine_Time = Machine_time;
       MessageBox.Show(Drawing_time.ToString());
        string message = "Full Time   " + ((Machine_time)).ToString() + "\n" +"Days   " +((Machine_time.Days)).ToString() + "\n" + "Hours   "+((Machine_time.Hours)).ToString() + "\n"
         + "Minutes  " + ((Machine_time.Minutes)).ToString()+ "\n"+ "Seconds  " + ((Machine_time.Seconds)).ToString();
     MessageBox.Show(message);
        saveSettings();
    }
...