1

我认为这个问题的标题不好,但我找不到更好的。

我想要做的是让用户能够设置倒数计时器。(看图1): 在此处输入图像描述

应用程序接受用户输入并检查用户选择了哪个时间单位,然后将其转换为秒并将值分配给一个int变量。

private int seconds = -1;

private void enable_button_Click(object sender, EventArgs e)
{
    int amount = Convert.ToInt32(time_numericUpDown.Value);
    string unit = tUnits_comboBox.Text;

    // Check what time is chosen then convert it to seconds
    if (unit == "Seconds")
        seconds = amount;
    else if (unit == "Minutes")
        seconds = amount * 60;
    else if (unit == "Hours")
        seconds = amount * 3600;
    else if (unit == "Days")
        seconds = amount * 86400;

    // Clock it!
    timer.Enabled = true;
}

然后,计时器应该以人类可读的格式显示时间,我使用以下代码:

private void timer_Tick(object sender, EventArgs e)
{
    // Verify if the time didn't pass
    if (seconds == 0)
    {
        // If the time is over, do the specified action
        timer.Enabled = false;
        operation(); // << This is the function that does the Action!
    }
    else
    {
        // Continue counting
        seconds -= 1;

        TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);

        string answer = string.Format("{0:D2}h:{1:D2}m:{2:D2}s",
                        timeSpan.Hours,
                        timeSpan.Minutes,
                        timeSpan.Seconds);

        status_label.Text = "Restarting in " + answer;
    }
}

当“秒”变量的值表示一天或更少时,这非常有效,但是当它超过 24 小时时,它只显示状态中的 24 小时。我究竟做错了什么?

( 问题 ):

在此处输入图像描述

4

6 回答 6

3

TotalHours如果这是您要显示的最大值,请使用。如果您查看 TimeSpan,它将在 Days 属性中也有一个值。

TimeSpan ts = new TimeSpan(48, 0, 0);
MessageBox.Show(ts.Days.ToString() + " - " + ts.Hours.ToString());   // 2 - 0
MessageBox.Show(ts.TotalHours.ToString());                           // 48

请注意,TotalHours 是一个表示小数小时数的双精度数:

TimeSpan ts = new TimeSpan(47, 59, 0);
MessageBox.Show(ts.Days.ToString() + " - " + ts.Hours.ToString());   // 1 - 23
MessageBox.Show(ts.TotalHours.ToString());                           // 47.98333

所以要得到你想要显示的值,你应该把它四舍五入:

 TimeSpan ts = new TimeSpan(47, 59, 0);
 MessageBox.Show(Math.Floor(ts.TotalHours).ToString());              // 47
于 2013-09-09T13:56:31.417 回答
3

所有不以开头的属性Total仅包含不适合下一个更高属性的其余部分。

换句话说:该Days属性将包含 value 1

于 2013-09-09T13:58:19.490 回答
2

如果您查看 中的属性列表TimeSpan,这可能更有意义。该Hours属性仅显示“小时”部分,就像您看到56的“秒”部分而不是172,796(即 2 天减去 4 秒)。还有Days一部分。您想使用TotalHoursdouble以小时为单位显示总量;类似于47.99995您的示例)和Math.Floor

    string answer = string.Format("{0:00}h:{1:D2}m:{2:D2}s",
                    Math.Floor(timeSpan.TotalHours),
                    timeSpan.Minutes,
                    timeSpan.Seconds);

在您的示例中,这将导致47:59:56.

于 2013-09-09T13:59:32.857 回答
1
TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);

当时间跨度的小时数超过 24 小时时,将被视为一天。所以你必须这样计算。

例子 :

如果总秒数:93600 表示 26 小时,而时间跨度将是 1 天 2 小时。

希望你能理解。

谢谢

于 2013-09-09T13:58:14.573 回答
1

尝试 TotalHours 而不是 Hours。

string answer = string.Format("{0:00}h:{1:D2}m:{2:D2}s",
                    timeSpan.TotalHours,
                    timeSpan.Minutes,
                    timeSpan.Seconds);
于 2013-09-09T13:58:24.527 回答
1

Hours获取当前 TimeSpan 结构表示的时间间隔的小时部分。(来自msdn)

还有一些您根本没有显示的“天”组件。

于 2013-09-09T13:59:48.497 回答