1

I am trying to create a countdown that includes hours.

private int time = 3660;        

public MainWindow()
{
    var vm = new TimerViewModel();

    InitializeComponent();

    // get display setting - 2 means extended
    int displayType = Screen.AllScreens.Length;

    // set the windows datacontext
    DataContext = vm;

    // set up the timedispatcher
    dt.Interval = new TimeSpan(0, 0, 1);
    dt.Tick += Timer_Tick;
}   

private void Timer_Tick(object sender, EventArgs e)
{
    switch(time)
    {
        case int x when x > 10 && x <= 20:                 
            TimerPreview.Foreground = Brushes.Orange;

            time--;
            break;

        .....................

        default:
            TimerPreview.Foreground = Brushes.LimeGreen;
            time--;
            break;
    }

    TimerPreview.Content = string.Format("00:{0:00}:{1:00}",  time / 60, time % 60);
}

I cannot work out how to get the countdown working correctly with hours. It works great with minutes and seconds.

TimerPreview.Content = string.Format("{0:00}:{1:00}:{2:00}", time ???, time ??? 60, time % 60);

I have tried a number of combinations but have failed to find a solution. What am I missing? Many thanks.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
CliveJ
  • 27
  • 1
  • 8
  • I feel like there is a lot of code that you are not posting on here, i barely understand what you are trying to do, please check out https://stackoverflow.com/help/mcve so we can help you better – nalnpir Oct 26 '18 at 17:05
  • Fair comment, sorry, I just didn't want to post too much clutter – CliveJ Oct 26 '18 at 20:24

2 Answers2

2

Use 3600 (the number of seconds in an hour), and use the modulus operator on the minutes just like you're doing on the seconds (since you want 60 minutes to appear to roll over into a new hour):

TimerPreview.Content =
    string.Format("{0:00}:{1:00}:{2:00}", time / 3600, (time / 60) % 60, time % 60);

//  320 -> 00:05:20
// 7199 -> 01:59:59
// 7201 -> 02:00:01
Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • That's great thank you so much. I didn't divide time by 60 for the minutes. Works perfectly. – CliveJ Oct 26 '18 at 20:26
1

Another (arguably more readable) option would be to use a TimeSpan to handle the formatting:

TimerPreview.Content = TimeSpan.FromSeconds(time).ToString(@"hh\:mm\:ss");

Result when time is 3660:

01:01:00


EDIT: Thanks to @GrantWinney for pointing out that the default string format for a TimeSpan is the same as above, unless the timespan is greater than a day, in which case it includes days as well. So you could just do:

TimerPreview.Content = TimeSpan.FromSeconds(time).ToString();
Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • Wow, you're right! I assumed the default would include days as well (`@"d\.hh\:mm\:ss"`); – Rufus L Oct 26 '18 at 17:53
  • 1
    Ahhh.. just tested it and it does include `Days` by default if there are 1 or more days represented by the `TimeSpan` – Rufus L Oct 26 '18 at 17:54
  • This works a treat too, thank you. I will not be doing days and the user will not be able to pass more than a couple of hours. – CliveJ Oct 26 '18 at 20:37