C#时间跨度到字符串问题

时间:2014-09-01 13:41:10

标签: c# string timer visual-c#-express-2010

你好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套分钟部分。 像这样: enter image description here

虽然应该是这段时间:

enter image description here

4 个答案:

答案 0 :(得分:2)

我看到你正在更新每个计时器滴答的标签,虽然它没有在代码中显示它看起来像你的计时器间隔可能设置为1秒,我是对的吗?

您做得不好的第一件事就是信任您之前在计时器中设置的1秒间隔,并将代码硬编码到该间隔。事实是你不能完全依赖定时器间隔,因为大多数定时器的分辨率时间大约为14-16毫秒,因此这不是测量时间的精确方法。

您应该使用使用Win32 API System.Diagnostics.StopwatchQueryPerformanceFrequency的时间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");
    }