Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need bigger variable than long 5

Status
Not open for further replies.

SH4F33

Programmer
Apr 1, 2005
58
MU
I'm writing a little program for personal use. Its very small.Its just a timer that shows how many days my computer has been on and writes the result to a text file every 10secs. Well I count seconds and convert them to the following format xdaysxhoursxminutesxseconds.I compiled it and everything run fine for some time and after that I get an overflow error. When I check the text file it says 2h17s.

The seconds are in a variable of type Long.

So if I need to run the program for about a year, what is the workaround?

I have this in a module

Code:
Option Explicit

' Duration
' By Quentin Zervaas [zervaas@strangeness.org]
' Use at will! Works as well as (better!) than mIRC's
' $duration function
' since it gives you multiple output options
' It's pretty easy to add more of your own
'depending on how you want it.
'
' Just add new cases, and define the strings accordingly
'(remember to allow spaces too.

Public Function Duration(TotalSeconds As Long, UpFormat As _
    Integer) As String
 
  ' Format = 0, 1, 2
  ' This determines the format of the time to be returned
  ' Type 0: 1d 4h 15m 47s
  ' Type 1: 1 day, 4:15:47
  ' Type 2: 1 day 4hrs 15mins 47secs
  ' Type else: Defaults to type 0
  
  Dim Seconds
  Dim Minutes
  Dim Hours
  Dim Days
  Dim DayString As String
  Dim HourString As String
  Dim MinuteString As String
  Dim SecondString As String
  
  Seconds = Int(TotalSeconds Mod 60)
  Minutes = Int(TotalSeconds \ 60 Mod 60)
  Hours = Int(TotalSeconds \ 3600 Mod 24)
  Days = Int(TotalSeconds \ 3600 \ 24)

  Select Case UpFormat
    Case 0
      DayString = "d"
      HourString = "h"
      MinuteString = "m"
      SecondString = "s"
    Case 1
      If Days = 1 Then DayString = " day, " _
      Else: DayString = " days, "
      HourString = ":"
      MinuteString = ":"
      SecondString = ""
    Case 2
      If Days = 1 Then DayString = " day " _
      Else: DayString = " days, "
      If Hours = 1 Then HourString = "hr " _
      Else: HourString = "hrs "
      If Minutes = 1 Then MinuteString = "min " _
      Else: MinuteString = "mins "
      If Seconds = 1 Then SecondString = "sec " _
      Else: SecondString = "secs"
    Case Else
      DayString = "d "
      HourString = "h "
      MinuteString = "m "
      SecondString = "s"
  End Select
  
  Select Case Days
    Case 0
      Duration = Format(Hours, "0") & HourString & _
            Format(Minutes, "00") & MinuteString & _
             Format(Seconds, "00") & SecondString
    Case Else
      Duration = Days & DayString & _
          Format(Hours, "0") & HourString & Format _
          (Minutes, "00") & MinuteString & _
           Format(Seconds, "00") & SecondString
    End Select
                 
End Function

These are the variables that I use in my form
Code:
Dim timStart As Date

Dim displayTime As String

Dim arr() As String

Dim intSeconds As Long

And on form load timStart = Time

And in my timer
Code:
Static intWrite As Byte

    intWrite = intWrite + 1
    
    If intWrite > 10 Then
    
        intWrite = 0
        
        WriteResult Label1.Caption 'Write Result is a function that writes the caption of label1 to a text file
        
    End If

    displayTime = Right("00" & Hour(Time - timStart), 2) & ":" & Right("00" & Minute(Time - timStart), 2) & ":" & Right("00" & Second(Time - timStart), 2)
  
    arr() = Split(displayTime, ":")
    
    intSeconds = CInt(arr(0) * 60 * 60) + CInt(arr(1) * 60) + CInt(arr(2))
  
    Me.Caption = displayTime
    
    Label1.Caption = Duration(intSeconds, 0)

Many thanks.
 
To avoid trying to look through all the code, can you tell me exactly which line of code produces the overflow error?

"Hmmm, it worked when I tested it....
 
You will want to look at floating point variable such as Double and/or Currency...
 
I have not read your code. Listen:

Do you want to have an output like:
"PC on for: 4345h 58234439m 354565356345234s" ??

As the seconds are greater than 60, increase the minutes.
As the minutes are greater than 60, increase the hours.
As the hours get greater than 24 increase the days.

So maybe add a Day string variable, i you need add also a string var calles weeks! Will you let the pc on for more than the maximum value of Long type (overflow the days)? I think you dont need a variable for weeks because you'll allready be out of memory.



That's all.
 
Make life simple -- your error is happening on the line:
intSeconds = CInt(arr(0) * 60 * 60) + CInt(arr(1) * 60) + CInt(arr(2))

Replace as follows:

Dim mTime As Date

mTime = Now()

intSeconds = (Hour(mTime) * 3600) + (Minute(mTime) * 60) + (Second(mTime))


"Hmmm, it worked when I tested it....
 
I think Trevil has the correct approach. Since a Date variable manages to store the number of seconds since some long-past date without a problem, it should work for you. Instead of using a seconds counter, just store the date/time your computer last booted, subtract that from the current date/time, and format the difference.


Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
If dtStart is your variable initialised on program start:
dtStart = Now()

Then the length of time your computer has been running is given by:
sngDuration = Now() - dtStart
strDuration = CStr(Int(sngDuration) & " days " & Format((sngDuration - int(sngDuration)),"hh:nn:ss")

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
 
I'd try changing TotalSeconds As Long to TotalSeconds As Double.

Maybe this world is another planet’s Hell.
Aldous Huxley

 
Besides this discussion, its interesting to know that Windows API has a similar function for formatting time intervals. Variable precision is also supported (min=1, max=7).
See the following code.
___
[tt]
Private Declare Function StrFromTimeInterval Lib "shlwapi" Alias "StrFromTimeIntervalA" (ByVal pszOut As String, ByVal cchMax As Long, ByVal dwTimeMS As Long, ByVal digits As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long

Function FormatTimeInterval(milliseconds As Long, Optional numDigits As Long = 7) As String
Dim S As String * 50
FormatTimeInterval = Left$(S, StrFromTimeInterval(S, Len(S), milliseconds, numDigits))
End Function

Private Sub Form_Load()
MsgBox "Time since Windows started: " & FormatTimeInterval(GetTickCount)
End
End Sub[/tt]
___

Sadly, this function has two major limitations.

1. It formats the time interval to hours only (No days if hours > 24).
2. Maximum time interval that can be formatted is about 1193 hrs (~ 50 days). Larger time intervals not supported.
 
Well the time will increment like normal time,60secs will increment 1 min, and 60min will increment 1hr and so on for the days.

So it won't be like 4345h 58234439m 354565356345234s

Instead the output will be something like 2d23h10m5s

So whe the hour becomes 24, days will be 3 and hours will be back to 00.

Well, Ive got more answers than I needed considering that I'll be the only one using this program.

Thanks to EVERYBODY(x*) for comments and suggestions.

Cheers.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top