views:

62

answers:

1

I have a timer that runs on the website. It will retrieve a timespan of how long a user has until their order expires. For the most part this works fine, the server will return the initial time remaining and the javascript will do the countdown. So it displays

2:30 2:29 2:28

Then for some reason, on some of the page loads (seems to happen when the timer has less than 60 seconds remaining), the formatting turns to

-1:0-45 -1:0-46 -1:0-47

This is the code responsible for formatting the timespan:

<%= (TimeRemaining.TotalMinutes - 1).ToString("N0") %>:<%= TimeRemaining.Seconds.ToString("N0").PadLeft(2,'0') %>

I've also just tried the following with the same result.

<%= String.Format("{0:0}:{1:00}", TimeRemaining.TotalMinutes-1, TimeRemaining.Seconds)%>

I also have a check on the TimeRemaining, if the TotalSeconds is <= 0, then it just returns a new TimeSpan(0), so it should never be going negative. It's not the javascript thats screwing up the countdown, because I can disable it and still see the messed up formatted time.

Is there a better/cleaner way to do this?

+4  A: 

One error I can see is that you shouldn't be subtracting one here:

TimeRemaining.TotalMinutes - 1

If there is less than thirty seconds remaining and you subtract one minute you will get a negative number.

TimeSpan timeRemaining = TimeSpan.FromSeconds(25);
string s = (timeRemaining.TotalMinutes - 1).ToString("N0");
Console.WriteLine(s);

Result:

-1

Instead you should round this number down to an integer (also called truncation). You can do this with Math.Floor, but it is also possible to just cast the number to an integer to achieve the same effect:

(int)TimeRemaining.TotalMinutes

As for the seconds, I don't know why that is going wrong. I assume it is because your time remaining can in fact go negative. The error seems to not be in the code you posted.

Mark Byers
If he doesn't display the remaining hours, days, etc. then showing TotalMinutes makes sense. But I don't understand why he subtracts 1. Maybe because of some rounding, ie would a Math.Floor help?
dtb
@dtb: Yeah, you are right.
Mark Byers
@Mark, from what I can tell it's because TotalMinutes appears to round. When I set it to 2 minutes remaining, it loads as TotalMinutes = 2, Seconds = 59. Resulting in 2:59 instead of 1:59.
Brandon
Also, the code that returns the TimeRemaining is `get { return _timeRemaining.TotalSeconds > 0 ? _timeRemaining : new TimeSpan(0); }` I don't think it should be possible to go below 0 using this.
Brandon
@Brandon: I have included a concrete example in my answer of a TimeSpan that is greater than zero but gives a negative number of minutes when formatted as you are doing. So your method of subtracting one is certainly wrong and should be fixed as I suggested. However I cannot explain the negative seconds, so I suspect that there is also a second error elsewhere in your code - probably in some code that you have not posted.
Mark Byers
@Mark, thanks for the info. I added a Math.Floor, and the issue seems to have gone away. Even the one with the seconds, though I'm not sure how. =\ Aside from the actual TimeRemaining being set, there is no other code related to the control.
Brandon