你好stackoverflow的人。当我尝试采用时间跨度并将其转换为字符串时,我遇到了问题。
以下是代码:
private void timer1_Tick(object sender, EventArgs e)
{
timeLeft = timeLeft - 1;
TimeLabel.Text = TimeSpan.FromMilliseconds(timeLeft).ToString("h'h 'm'm 's's'");
}
请注意timeLeft
以毫秒为单位。
然而,每当我试图通过这个,我得到2套分钟部分。 像这样:
虽然应该是这段时间:
答案 0 :(得分:2)
我看到你正在更新每个计时器滴答的标签,虽然它没有在代码中显示它看起来像你的计时器间隔可能设置为1秒,我是对的吗?
您做得不好的第一件事就是信任您之前在计时器中设置的1秒间隔,并将代码硬编码到该间隔。事实是你不能完全依赖定时器间隔,因为大多数定时器的分辨率时间大约为14-16毫秒,因此这不是测量时间的精确方法。
您应该使用使用Win32 API System.Diagnostics.Stopwatch和QueryPerformanceFrequency的时间QueryPerformanceCounter类。由于Windows不是Real Time Operation System,因此这些是更可靠的方法和快速测量时间的方法。
至于代码的外观如何使用我让一个应该很容易适应你的样本。除此之外,我还为您的TimeSpan提供了解决方案 - 字符串翻译问题。
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
Console.WriteLine("Starting..");
sw.Start();
Console.ReadLine();
sw.Stop();
Console.WriteLine("Elapsed time {0}:{1}:{2}:{3}", sw.Elapsed.Hours.ToString("00"), sw.Elapsed.Minutes.ToString("00"), sw.Elapsed.Seconds.ToString("00"), sw.Elapsed.Milliseconds);
}
}
使用System.Diagnostics.Stopwatch属性时要小心,使用Elapsed.Ticks属性和ElapsedTicks属性有很大的不同,它解释了here。
希望它有所帮助!!
答案 1 :(得分:1)
由于不能确保计时器将在每毫秒被触发,因此您必须保存一个开始时间,然后通过从当前时间减去开始时间来计算经过时间。
以下是一段代码摘要:
private DateTime _StartTime;
private void OnCheckBoxTimerEnabledCheckedChanged(object sender, EventArgs e)
{
_StartTime = DateTime.UtcNow;
timer.Enabled = checkBoxTimerEnabled.Checked;
}
private void OnTimerTick(object sender, System.EventArgs e)
{
var now = DateTime.UtcNow;
labelTimeElapsed.Text = (now - _StartTime).ToString("h'h 'm'm 's's'");
}
在这种情况下,你也不需要每毫秒发射一次计时器。只需每隔100毫秒触发一次就足以让用户眼前一亮。
另一个提示:
如果您需要自己计算相对时间,则应始终坚持DateTime.UtcNow
而不是DateTime.Now
。因此,当您从正常时间切换到夏令时,反之亦然,当您的计时器运行时,您不会遇到麻烦。
答案 2 :(得分:0)
您的代码没有任何问题。但我想你认为自上面的例子显示以来 2:02:56而另一个02:03:00相当接近错过了大约3200毫秒...
timeLeft的实际值是什么?
Read some more in the documentation on customizing timespan strings
答案 3 :(得分:0)
使用计时器的Tick事件来跟踪传球时间会导致Lasse V. Karlsen在你的问题评论中提到不准确。
您要做的是在计时器开始时存储时间戳(DateTime.Now),并在每次计时器滴答时将其与新的DateTime.Now进行比较,如下所示:
DateTime timestamp;
TimeSpan timeLeft;
private void begin_timer()
{
timestamp = DateTime.Now;
timer1.start();
}
private void timer1_Tick(object sender, EventArgs e)
{
timeLeft = DateTime.Now - timestamp;
TimeLabel.Text = timeLeft.ToString("HH:mm:ss.fff");
}