制作简单准确秒表的最佳方法
The best way to make a simple and accurate stopwatch
我有一个项目,我必须做一个秒表。它可以工作,但与 Windows 计时器相比并不准确。另外,我想知道是否有另一种有效且简单的方法可以做到这一点,如果有,我该怎么做?。 Timer的间隔为1.
这是我的代码:
Dim min As Integer = 30
Dim seg As Integer = 59
Dim mseg As Integer = 99
Private Sub tmTimer_Tick(sender As Object, e As EventArgs) Handles tmTimer.Tick
If lblStopWatch.Text = "00:00:00" Then
lblStopWatch.ForeColor = Color.DarkGray
tmTimer.Enabled = False
min = 30
seg = 59
mseg = 99
Else
mseg -= 1
If mseg < 0 Then
mseg = 99
seg -= 1
If seg < 0 Then
seg = 59
min -= 1
End If
End If
If min < 10 And seg < 10 And mseg < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":0" + seg.ToString + ":0" + mseg.ToString
ElseIf min < 10 And seg < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":0" + seg.ToString + ":" + mseg.ToString
ElseIf min < 10 And mseg < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":" + seg.ToString + ":0" + mseg.ToString
ElseIf seg < 10 And mseg < 10 Then
lblStopWatch.Text = min.ToString + ":0" + seg.ToString + ":0" + mseg.ToString
Else
If mseg < 10 Then
lblStopWatch.Text = min.ToString + ":" + seg.ToString + ":0" + mseg.ToString
ElseIf seg < 10 Then
lblStopWatch.Text = min.ToString + ":0" + seg.ToString + ":" + mseg.ToString
ElseIf min < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":" + seg.ToString + ":" + mseg.ToString
Else
lblStopWatch.Text = min.ToString + ":" + seg.ToString + ":" + mseg.ToString
End If
End If
End If
End Sub
这是可以启动计时器的按钮:
Private Sub btnAcept_Click(sender As Object, e As EventArgs) Handles btnAcept.Click
lblCronometro.ForeColor = Color.RoyalBlue
lblCronometro.Text = "30:00:00"
tmCronometro.Enabled = True
tmCronometro.Start()
End Sub
如果示例是用 C# 或 vb,我可以同时获得。
谢谢
.NET Framework 包含 Stopwatch
class,因此您应该使用它。它非常准确,至少在您的代码按时执行其方法的程度上是这样。它有 Start
、Stop
、Restart
和 Reset
的方法,它提供了作为 TimeSpan
的经过时间,您可以直接格式化而不是所有的连接.使用 Timer
的唯一目的是允许您在 Label
中显示当前经过的时间。例如
Private ReadOnly stopwatch As New Stopwatch
Private Sub startButton_Click(sender As Object, e As EventArgs) Handles startButton.Click
DisplayElapsedTime()
stopwatch.Start()
displayTimer.Start()
startButton.Enabled = False
stopButton.Enabled = True
restartButton.Enabled = True
resetButton.Enabled = False
End Sub
Private Sub stopButton_Click(sender As Object, e As EventArgs) Handles stopButton.Click
stopwatch.Stop()
displayTimer.Stop()
DisplayElapsedTime()
startButton.Enabled = True
stopButton.Enabled = False
restartButton.Enabled = False
resetButton.Enabled = True
End Sub
Private Sub restartButton_Click(sender As Object, e As EventArgs) Handles restartButton.Click
stopwatch.Restart()
DisplayElapsedTime()
End Sub
Private Sub resetButton_Click(sender As Object, e As EventArgs) Handles resetButton.Click
stopwatch.Reset()
DisplayElapsedTime()
End Sub
Private Sub displayTimer_Tick(sender As Object, e As EventArgs) Handles displayTimer.Tick
DisplayElapsedTime()
End Sub
Private Sub DisplayElapsedTime()
elapsedTimeLabel.Text = stopwatch.Elapsed.ToString("m\:ss\.fff")
End Sub
提示
如果您想自己做而不是使用现有的 StopWatch
class,另一种选择是跟踪秒表开始的时间 (start
) 和秒表有多长时间 运行 (elapsed
).
有了 start
值,我们可以计算计时器的 Tick
事件中的 elapsed
时间,例如:
// elapsed is a TimeSpan object
elapsed = DateTime.Now - start;
如果我们添加停止秒表然后再次启动它的功能(无需重置),那么我们必须考虑 "downtime"。我们可以通过从当前时间减去 elapsed
时间并使用 that 值作为开始时间来在 Start
按钮单击事件中执行此操作:
// start is a DateTime object
start = DateTime.Now.Subtract(elapsed);
然后,当我们想向用户显示经过的时间时,我们可以只使用我们的 elapsed
字段并将其格式化为:hours:minutes:seconds.milliseconds
使用自定义格式字符串。
// I noticed you're doing a countdown timer, so we want to display the difference
// between the original duration of 30 minutes and the elapsed time we've been running
lblStopwatch.Text = (duration - elapsed).ToString("hh\:mm\:ss\.ff");
回答
如果这些提示还不够,这里有一个使用该策略的示例项目:
public partial class Form1 : Form
{
private DateTime _startTime;
private TimeSpan _elapsedTime;
// The starting duration for the countdown timer
private readonly TimeSpan _duration = TimeSpan.FromMinutes(30);
public Form1()
{
InitializeComponent();
ResetTimer();
}
private void ResetTimer()
{
_startTime = DateTime.Now;
_elapsedTime = TimeSpan.Zero;
UpdateStopwatchDisplay();
}
private void UpdateStopwatchDisplay()
{
// Display the current duration to the user
lblStopwatch.ForeColor = timer1.Enabled ? Color.RoyalBlue : Color.DarkGray;
lblStopwatch.Text = (_duration - _elapsedTime).ToString("hh\:mm\:ss\.ff");
}
private void btnStart_Click(object sender, EventArgs e)
{
// Subtract 'elapsed' from 'now' to account for any stoppage time
_startTime = DateTime.Now.Subtract(_elapsedTime);
UpdateStopwatchDisplay();
timer1.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
timer1.Stop();
UpdateStopwatchDisplay();
}
private void btnReset_Click(object sender, EventArgs e)
{
ResetTimer();
}
private void timer1_Tick(object sender, EventArgs e)
{
// Update elapsed time
_elapsedTime = DateTime.Now.Subtract(_startTime);
// Stop the timer if we've reached our duration
if (_elapsedTime >= _duration)
{
_elapsedTime = _duration;
timer1.Stop();
}
UpdateStopwatchDisplay();
}
}
我有一个项目,我必须做一个秒表。它可以工作,但与 Windows 计时器相比并不准确。另外,我想知道是否有另一种有效且简单的方法可以做到这一点,如果有,我该怎么做?。 Timer的间隔为1.
这是我的代码:
Dim min As Integer = 30
Dim seg As Integer = 59
Dim mseg As Integer = 99
Private Sub tmTimer_Tick(sender As Object, e As EventArgs) Handles tmTimer.Tick
If lblStopWatch.Text = "00:00:00" Then
lblStopWatch.ForeColor = Color.DarkGray
tmTimer.Enabled = False
min = 30
seg = 59
mseg = 99
Else
mseg -= 1
If mseg < 0 Then
mseg = 99
seg -= 1
If seg < 0 Then
seg = 59
min -= 1
End If
End If
If min < 10 And seg < 10 And mseg < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":0" + seg.ToString + ":0" + mseg.ToString
ElseIf min < 10 And seg < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":0" + seg.ToString + ":" + mseg.ToString
ElseIf min < 10 And mseg < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":" + seg.ToString + ":0" + mseg.ToString
ElseIf seg < 10 And mseg < 10 Then
lblStopWatch.Text = min.ToString + ":0" + seg.ToString + ":0" + mseg.ToString
Else
If mseg < 10 Then
lblStopWatch.Text = min.ToString + ":" + seg.ToString + ":0" + mseg.ToString
ElseIf seg < 10 Then
lblStopWatch.Text = min.ToString + ":0" + seg.ToString + ":" + mseg.ToString
ElseIf min < 10 Then
lblStopWatch.Text = "0" + min.ToString + ":" + seg.ToString + ":" + mseg.ToString
Else
lblStopWatch.Text = min.ToString + ":" + seg.ToString + ":" + mseg.ToString
End If
End If
End If
End Sub
这是可以启动计时器的按钮:
Private Sub btnAcept_Click(sender As Object, e As EventArgs) Handles btnAcept.Click
lblCronometro.ForeColor = Color.RoyalBlue
lblCronometro.Text = "30:00:00"
tmCronometro.Enabled = True
tmCronometro.Start()
End Sub
如果示例是用 C# 或 vb,我可以同时获得。 谢谢
.NET Framework 包含 Stopwatch
class,因此您应该使用它。它非常准确,至少在您的代码按时执行其方法的程度上是这样。它有 Start
、Stop
、Restart
和 Reset
的方法,它提供了作为 TimeSpan
的经过时间,您可以直接格式化而不是所有的连接.使用 Timer
的唯一目的是允许您在 Label
中显示当前经过的时间。例如
Private ReadOnly stopwatch As New Stopwatch
Private Sub startButton_Click(sender As Object, e As EventArgs) Handles startButton.Click
DisplayElapsedTime()
stopwatch.Start()
displayTimer.Start()
startButton.Enabled = False
stopButton.Enabled = True
restartButton.Enabled = True
resetButton.Enabled = False
End Sub
Private Sub stopButton_Click(sender As Object, e As EventArgs) Handles stopButton.Click
stopwatch.Stop()
displayTimer.Stop()
DisplayElapsedTime()
startButton.Enabled = True
stopButton.Enabled = False
restartButton.Enabled = False
resetButton.Enabled = True
End Sub
Private Sub restartButton_Click(sender As Object, e As EventArgs) Handles restartButton.Click
stopwatch.Restart()
DisplayElapsedTime()
End Sub
Private Sub resetButton_Click(sender As Object, e As EventArgs) Handles resetButton.Click
stopwatch.Reset()
DisplayElapsedTime()
End Sub
Private Sub displayTimer_Tick(sender As Object, e As EventArgs) Handles displayTimer.Tick
DisplayElapsedTime()
End Sub
Private Sub DisplayElapsedTime()
elapsedTimeLabel.Text = stopwatch.Elapsed.ToString("m\:ss\.fff")
End Sub
提示
如果您想自己做而不是使用现有的 StopWatch
class,另一种选择是跟踪秒表开始的时间 (start
) 和秒表有多长时间 运行 (elapsed
).
有了 start
值,我们可以计算计时器的 Tick
事件中的 elapsed
时间,例如:
// elapsed is a TimeSpan object
elapsed = DateTime.Now - start;
如果我们添加停止秒表然后再次启动它的功能(无需重置),那么我们必须考虑 "downtime"。我们可以通过从当前时间减去 elapsed
时间并使用 that 值作为开始时间来在 Start
按钮单击事件中执行此操作:
// start is a DateTime object
start = DateTime.Now.Subtract(elapsed);
然后,当我们想向用户显示经过的时间时,我们可以只使用我们的 elapsed
字段并将其格式化为:hours:minutes:seconds.milliseconds
使用自定义格式字符串。
// I noticed you're doing a countdown timer, so we want to display the difference
// between the original duration of 30 minutes and the elapsed time we've been running
lblStopwatch.Text = (duration - elapsed).ToString("hh\:mm\:ss\.ff");
回答
如果这些提示还不够,这里有一个使用该策略的示例项目:
public partial class Form1 : Form
{
private DateTime _startTime;
private TimeSpan _elapsedTime;
// The starting duration for the countdown timer
private readonly TimeSpan _duration = TimeSpan.FromMinutes(30);
public Form1()
{
InitializeComponent();
ResetTimer();
}
private void ResetTimer()
{
_startTime = DateTime.Now;
_elapsedTime = TimeSpan.Zero;
UpdateStopwatchDisplay();
}
private void UpdateStopwatchDisplay()
{
// Display the current duration to the user
lblStopwatch.ForeColor = timer1.Enabled ? Color.RoyalBlue : Color.DarkGray;
lblStopwatch.Text = (_duration - _elapsedTime).ToString("hh\:mm\:ss\.ff");
}
private void btnStart_Click(object sender, EventArgs e)
{
// Subtract 'elapsed' from 'now' to account for any stoppage time
_startTime = DateTime.Now.Subtract(_elapsedTime);
UpdateStopwatchDisplay();
timer1.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
timer1.Stop();
UpdateStopwatchDisplay();
}
private void btnReset_Click(object sender, EventArgs e)
{
ResetTimer();
}
private void timer1_Tick(object sender, EventArgs e)
{
// Update elapsed time
_elapsedTime = DateTime.Now.Subtract(_startTime);
// Stop the timer if we've reached our duration
if (_elapsedTime >= _duration)
{
_elapsedTime = _duration;
timer1.Stop();
}
UpdateStopwatchDisplay();
}
}