Register
Wednesday, September 08, 2010
 
 DBAs And ProgrammersBlog
  
News! Minimize
   
 
 Print   
 
Misc Blog Stuff Minimize
   
 
 Print   
 
The Reluctant DBA Minimize
 
 
 
 Print   
 
Reluctant DBA Minimize
   
 
  
 
Reluctant DBA Minimize
   
 
  
 
The Reluctant DBA Minimize
 
Jul4

Written by:CarpDeus
7/4/2008 6:55 AM 

I've been playing around with writing a little application for my handheld, a version of the cipher solver on my personal site. And, to make it more interesting, I wanted to be able to see how long it took me to solve each puzzle. Not finding a good class to use, I wrote one myself using the TimeSpan class.

Let's first look at the global variables:

/// <summary>
 /// Starting time
 /// </summary>
 DateTime startingTimer;

 /// <summary>
 /// Total Ticks processed
 /// </summary>
 Int64 totalTicks = 0;

 /// <summary>
 /// Is the stopwatch currently running
 /// </summary>
 public bool TimerRunning = false;

I think they are all fairly self-explanatory.

Now, the simple mechanics of starting and stopping the timer. There are four methods: StartTimer(), StopTimer(), PauseTimer() and RestartTimer(). The only difference between StartTimer() and RestartTimer() is that StartTimer() sets the totalTicks to 0. PauseTimer() actually just calls StopTimer(), which adds to the running tick count in totalTicks.

/// <summary>
 /// Start the timer running
 /// </summary>
 public void StartTimer()
 {
  TimerRunning = true;
  totalTicks = 0;
  startingTimer = DateTime.Now;
 }


 /// <summary>
 /// Stop the timer running
 /// </summary>
 public void StopTimer()
 {
  TimerRunning = false;
  totalTicks += DateTime.Now.Subtract(startingTimer).Ticks;
 }

 /// <summary>
 /// Pause the timer
 /// </summary>
 public void PauseTimer()
 {
  StopTimer();
 }

 /// <summary>
 /// Start the timer to add to the elapsed timer
 /// </summary>
 public void RestartTimer()
 {
  if (!TimerRunning)
  {
   TimerRunning = true;
   startingTimer = DateTime.Now;
  }
 }

As you can see, this is a fairly simple class. Whenever we start timing we set the startingTimer value so we can query it later and determine how many ticks have elapsed. Then when we stop the timer we take the totalTicks value and add to it the number of ticks difference between the current date time and the starting date time using the DateTime Subtract method, which returns a TimeSpan struct.

That's all the boring stuff (though my finaceé would say this is all boring), so let's look at formatting the output of the elapsed time, starting by looking at the code:

/// <summary>
 /// Get the elapsed time as a string formatted in HHH:MM:SS
 /// </summary>
 /// <returns>elapsed time as a string formatted in HHH:MM:SS</returns>
 public string GetDuration()
 {
  Int64 printableTicks = totalTicks; ;
  if (TimerRunning)
  {
   printableTicks =  DateTime.Now.Subtract(startingTimer).Ticks + totalTicks;
  }
  TimeSpan outputSpan = new TimeSpan(printableTicks);
  string retVal = "";
   if (outputSpan.TotalHours > 1)
   retVal = string.Format("{0:00}:{1:00}:{2:00}", (int)outputSpan.TotalHours, outputSpan.Minutes, outputSpan.Seconds);
  else
   retVal = string.Format("{0:00}:{1:00}", outputSpan.Minutes, outputSpan.Seconds);
  if (retVal.StartsWith ("17597350:"))
   retVal = "00:00";
  return retVal;
 }

We do this by outputting a value based on the number of ticks that have elapsed. We start by creating a printableTicks variable which is the equivalent of totalTicks. Then we determine if the stop watch is still running. If it is (TimerRunning is true), then we add to the printableTicks the elapsed time.

Note: The downloadable code actually accomplishes that in the one line of code demonstrated below but that's because it seems to have made a difference in the size of the code produced for the handheld. In most cases, I'd prefer the version above for general readiblity.

Int64 printableTicks = totalTicks + (TimerRunning ? DateTime.Now.Subtract(startingTimer).Ticks : 0);

Now we use the string.Format command to output the results.  If the time has been less than an hour, we output it in MM:SS format, otherwise we use HHH:MM:SS format. The last bit of code, the one that checks to see if the return string has a large number in it is because of issues related to the structs not having null evaluations.

And that's it. You can download the source code here.

Tags:

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment  Cancel 
 
 
  
 
Privacy Statement | Terms Of Use Copyright 2001-2008 by ReluctantDBA.com