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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

algorithm assistance

Status
Not open for further replies.

ChewDoggie

Programmer
Mar 14, 2005
604
US
g'morning all!

I need some assistance with an algorithm (I'm embarrassed to say). I have a time in a db (TimeSave), recorded in milliseconds, that I need to convert to Hours & Minutes & Seconds & Milliseconds on a VB Form. My code currently looks like this:

Code:
    If TimeSave <> 0 Then
        secs = TimeSave / 1000
        msecs = TimeSave Mod 1000
        If secs > 60 Then
            mins = secs / 60
            secs = secs Mod 60
            If mins > 60 Then
                hrs = mins / 60
                mins = mins Mod 60
            End If
        End If
    End If
    If hrs = 0 Then
        txtHours.Text = ""
    Else
        txtHours.Text = hrs
    End If
    If mins = 0 Then
        txtMinutes.Text = ""
    Else
        txtMinutes.Text = mins
    End If
    If secs = 0 Then
        txtSeconds.Text = ""
    Else
        txtSeconds.Text = secs
    End If
    If msecs = 0 Then
        txtMSeconds.Text = ""
    Else
        txtMSeconds.Text = msecs
    End If

I seems to work kind of OK, but the minutes always resolves to 1 more minute than I need. Any help would be appreciated.



ciao for niao!

AMACycle

American Motorcyclist Association
 
Try

tmp = TimeSave
hours = tmp \ 3600
tmp = tmp mod 3600
minutes = tmp \ 60
seconds = tmp mod 60


Hope this helps
 
I would try this:
secs = Int(TimeSave / 1000)
msecs = TimeSave Mod 1000
If secs > 60 Then
mins = Int(secs / 60)
secs = secs Mod 60
If mins > 60 Then
hrs = Int(mins / 60)
mins = mins Mod 60
End If

[red]"... isn't sanity really just a one trick pony anyway?! I mean, all you get is one trick, rational thinking, but when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick[/red]
 
It looks like timesave is an integer variable. Is this true?

What are some typical values for the TimeSave variable?

If this is a Date variable. There are some nice built-in functions like Hour, Minute, and Second that you can use.

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
George,

TimeSave is defined in the db as a double. For a 12 minute race time, the value in the db is 720000.000. For a 1 hour, 12 minutes and 59 second race time, the value in the db is 4379000.000.

HTH


ciao for niao!

AMACycle

American Motorcyclist Association
 
In any case, I think the secs > 60 and mins > 60 should be > 59

Alan

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Adding the Int function as I showed above worked for me.

[red]"... isn't sanity really just a one trick pony anyway?! I mean, all you get is one trick, rational thinking, but when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick[/red]
 
Here's another method using the built-in vb functions.

Code:
    Dim TimeSave As Double
    Dim dteSave As Date
    Dim Milliseconds As Double
    
    TimeSave = 4379050
    
    Milliseconds = CInt(((TimeSave / 1000) - CInt(TimeSave / 1000)) * 1000)
    
    dteSave = (TimeSave / 1000) / 86400
    
    MsgBox Hour(dteSave) & " Hour"
    MsgBox Minute(dteSave) & " Minute"
    MsgBox Second(dteSave) & " Seconds"
    MsgBox Milliseconds & " Milliseconds"

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
Here's another API solution to complement Hypetia's (and involves a bit of a scam):
Code:
[blue]Option Explicit

' Cheat, so we don't have to muck about with high and low dwords ...
Private Type FileTime
    Milliseconds As Currency
End Type

Private Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FileTime, lpSystemTime As SYSTEMTIME) As Long

' Starts at 1st of Jan 1601
Private Type SYSTEMTIME
        wYear As Integer
        wMonth As Integer
        wDayOfWeek As Integer
        wDay As Integer
        wHour As Integer
        wMinute As Integer
        wSecond As Integer
        wMilliseconds As Integer
End Type

Private Sub Command1_Click()
    Dim myFileTime As FileTime
    Dim mySysTime As SYSTEMTIME
    Dim strMsg As String
    
    myFileTime.Milliseconds = 2678400000# - 1
    FileTimeToSystemTime myFileTime, mySysTime
    
    ' Without further manipulation this will correctly return up to 31 days - 1 millisecond  of elapsed time
    strMsg = mySysTime.wDay - 1 & " day"
    strMsg = strMsg & vbCrLf & mySysTime.wHour & " hour"
    strMsg = strMsg & vbCrLf & mySysTime.wMinute & " minute"
    strMsg = strMsg & vbCrLf & mySysTime.wSecond & " second"
    strMsg = strMsg & vbCrLf & mySysTime.wMilliseconds & " millisecond"
    
    MsgBox strMsg
End Sub[/blue]
 
Code:
Public Function basMilliSec2MsTime(dblMiliSec As Double) As String

    'TimeSave is defined in the db as a double. _
     For a 12 minute race time, the value in the db is 720000.000. _
     For a 1 hour, 12 minutes and 59 second race time, _
     the value in the db is 4379000.000.

    'Time, in Ms. Speak is a floating point value.  The Integer _
     Portion is the number of days since 12/30/1899. _
     The decimal (fraction) represents the proportion of a day.
     
    'The number of seconds in a full day is easily calculated: _
     24 Hrs * 60 Min / Hr * 60 Sec / Min = 86400. _
     Milli is just the prefix for 1000, so adding the three amigos _
     (or zeros) returns 86400000 Milli-seconds per day.

    'In Ms. Speak, the Milliseconds will never be seen, as the LCD _
     for their functions is ye standard Second.  Further, Ms Standard _
     functions will do the other intervals with (almost) no efort, _
     so deal with these early (but not often).

    Dim sngMiliSec As Single
    sngMiliSec = dblMiliSec Mod 1000

    'Now, just convert the dbl to a standard Ms. Speak Var
    Dim MsTime As Date
    MsTime = CDate(dblMiliSec / 86400000)

    'If the Time thinnggyyyyy would always be less than a day AND _
     we reall could ignore the milliseconds the following would be sufficient _
    basMilliSec2MsTime = Format(MsTime, "h:m:s") _
     Alas, alack and awry chances are somewhere between nil and null for either _
     so we need to strive on.

    'Having already established the value of the milliseconds , we still _
    need the number of days:
    Dim intDays As Integer
    intDays = CLng(MsTime)      'WoW wasn't that trivial?

    'So, it remains only to format the return value.  As already _
     noted, attempting to use a built in function or format _
     is a safe and sure way to loose the MilliSeconds.  It is equally _
     awkward to attempt to represent the Days in a standard Ms Speak _
     formatting exercise, so we resort to another LCD (string / Text):

    basMilliSec2MsTime = intDays & " days, " _
                       & Format(MsTime, "h") & " Hours " _
                       & Format(MsTime, "m") & " Minutes " _
                       & Format(MsTime, "s") & " Seconds and " _
                       & Format(sngMiliSec, "0.##") & " Milliseconds"
End Function

Stripped of the drivel of commentary, the asbove is about seven statements, three declarations, three calculations and one output/format.

Enjoy, use, complain, critique or correct. Your choce.




MichaelRed


 
> critique

You might want to chuck some additional known test data at your function.

As a simple example passing neither 15# * 24 * 60 * 60 * 1000 nor 15.5 * 24 * 60 * 60 * 1000 to the function produce the correct result (in fact for most values except the two example values poseted in the thread it gets the answer wrong)

And it will error out if you pass more than 2147483647 milliseconds
 
I ended up using TomThumbKP's method, which closely mirrored mine, only he used "Int" to arrive at certain values. I've thrown many test cases at the algorithm, each passing with flying colors.

Thanks to all!



ciao for niao!

AMACycle

American Motorcyclist Association
 
Point of using currency is that it is the largest available integer in VB, not so?

Bob
 
Partially. The main point is that it is a 64-bit integer, which is the same size as two VB longs
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top