Time calculations
Moderators: Dorian (MJT support), JRL
- Phil Pendlebury
- Automation Wizard
- Posts: 543
- Joined: Tue Jan 16, 2007 9:00 am
- Contact:
Time calculations
Greetings,
I though this may be an interesting discussion. I have searched around and found a few bits but nothing in concrete.
I recently wrote a script that takes a number of frames (frames are a fraction of a second - of varying values depending on frame "rate" used in the music and film industry) and converts it to hours minutes and seconds (and frames).
Also vice versa. You enter Hours Minutes Seconds Frames and it will convert to the total number of frames. (that part is easy - very simple math).
I have also done similar scripts for working out delay times / BPM and other things (music related)
The time calculations always cause me a bit of trouble.
What I end up doing is looping through a script that takes the total seconds and deducts 60 while adding 1 to the minute counter etc. Or dividing seconds by 3600 which give you hours etc.
I have used VBScript to calculate time differences but I can't find anything relevant to calculate actual time mathematics.
Let me give you a really simple example:
Let's say that I am giving you a random number between 1 and 100,000
That is a number of seconds.
How would you guys work out how many Hours, Minutes and Seconds that number will contain - without using the two methods I mentioned above?
Is it possible to find maybe a VB Script command that will simply give you the answer.
For example ( I know my code is wrong but just as an example)
Let>seconds = 123456
VBEvalTimeFromSeconds - (seconds) result_variable
MDL>%seconds% seconds = %result_variable%
Message would read: 123456 seconds = 34:17:36
(or similar).
As I said, my time scripts are working well already and I am sure that I will always have to do my own calculations on frame rates but I was just interested to see what you guys thought.
nb: You can download the complied Frame Rate Calc from here:
http://www.box.net/shared/xujuimo8z6
Cheers,
PS. This may be better in the discussion section. Whatever you moderators think is fine with me.
I though this may be an interesting discussion. I have searched around and found a few bits but nothing in concrete.
I recently wrote a script that takes a number of frames (frames are a fraction of a second - of varying values depending on frame "rate" used in the music and film industry) and converts it to hours minutes and seconds (and frames).
Also vice versa. You enter Hours Minutes Seconds Frames and it will convert to the total number of frames. (that part is easy - very simple math).
I have also done similar scripts for working out delay times / BPM and other things (music related)
The time calculations always cause me a bit of trouble.
What I end up doing is looping through a script that takes the total seconds and deducts 60 while adding 1 to the minute counter etc. Or dividing seconds by 3600 which give you hours etc.
I have used VBScript to calculate time differences but I can't find anything relevant to calculate actual time mathematics.
Let me give you a really simple example:
Let's say that I am giving you a random number between 1 and 100,000
That is a number of seconds.
How would you guys work out how many Hours, Minutes and Seconds that number will contain - without using the two methods I mentioned above?
Is it possible to find maybe a VB Script command that will simply give you the answer.
For example ( I know my code is wrong but just as an example)
Let>seconds = 123456
VBEvalTimeFromSeconds - (seconds) result_variable
MDL>%seconds% seconds = %result_variable%
Message would read: 123456 seconds = 34:17:36
(or similar).
As I said, my time scripts are working well already and I am sure that I will always have to do my own calculations on frame rates but I was just interested to see what you guys thought.
nb: You can download the complied Frame Rate Calc from here:
http://www.box.net/shared/xujuimo8z6
Cheers,
PS. This may be better in the discussion section. Whatever you moderators think is fine with me.
Phil Pendlebury - Linktree
Hi Phil,
It can be calculated very simply using Macro Schedulers DIV and MOD arithimetic operators in a complex expression.
Gale
It can be calculated very simply using Macro Schedulers DIV and MOD arithimetic operators in a complex expression.
Code: Select all
Input>iElapsedSeconds,Enter integer number of elapsed seconds,0
Let>iInputSeconds=%iElapsedSeconds%
Let>iHours={%iElapsedSeconds% div 3600}
Let>iElapsedSeconds={%iElapsedSeconds% mod 3600}
Let>iMinutes={%iElapsedSeconds% div 60}
Let>iSeconds={%iElapsedSeconds% mod 60}
MDL>%iInputSeconds%=%iHours%:%iMinutes%:%iSeconds%
- Phil Pendlebury
- Automation Wizard
- Posts: 543
- Joined: Tue Jan 16, 2007 9:00 am
- Contact:
Thanks Gale that's a great solution.
I didn't think of div and mod.... Which probably sounds daft but that's just me.
I didn't think of div and mod.... Which probably sounds daft but that's just me.
Phil Pendlebury - Linktree
- Phil Pendlebury
- Automation Wizard
- Posts: 543
- Joined: Tue Jan 16, 2007 9:00 am
- Contact:
However...
It seems that div and mod are incompatible with float numbers... Let me explain:
Frame Rate is a division of seconds. It can be 24, 25, 29.97, 30 or even some other numbers.
So take 123456 frames for example this actually equals 4938.24 seconds.
When that amount is used to start the hours minutes seconds calculation - the script throws up an error because it is a float number.
It seems that div and mod are incompatible with float numbers... Let me explain:
Frame Rate is a division of seconds. It can be 24, 25, 29.97, 30 or even some other numbers.
So take 123456 frames for example this actually equals 4938.24 seconds.
When that amount is used to start the hours minutes seconds calculation - the script throws up an error because it is a float number.
Phil Pendlebury - Linktree
That's why the "round" function was invented.When that amount (4938.24 seconds) is used to start the hours minutes seconds calculation - the script throws up an error because it is a float number.
Modified Gales script a bit by adding "round" to the first Let> line. Also reversed the "iInputSeconds" and the "iElapsedSeconds" variables in the first two lines. BTW, nice, well conceived script Gale!
And if you think you need that fraction of a second added on the result time, that could easily be accomplished by stripping the characters to the right of the decimal point using the Separate> function. Then pasting those decimal characters on the end so the result would look like:
HH:MM:SS.SSS
Code: Select all
Input>iInputSeconds,Enter integer number of elapsed seconds,0
Let>iElapsedSeconds={round(%iInputSeconds%)}
Let>iHours={%iElapsedSeconds% div 3600}
Let>iElapsedSeconds={%iElapsedSeconds% mod 3600}
Let>iMinutes={%iElapsedSeconds% div 60}
Let>iSeconds={%iElapsedSeconds% mod 60}
MDL>%iInputSeconds%=%iHours%:%iMinutes%:%iSeconds%
- Phil Pendlebury
- Automation Wizard
- Posts: 543
- Joined: Tue Jan 16, 2007 9:00 am
- Contact:
Hi again guys.
OK well this is ending up pretty similar to my original script.
If you look at the file I linked to - you would see that the fraction of seconds is required and indeed essential to the calculations.
Also there is the issues with decimal place being different for different languages. So I used the old trick:
At various points throughout my script. (Many of my users are French - who use a comma as decimal point).
I then ended up using Trunc and Frac to do my final calculations.
So in fact this code is now not much more simple than what I already have. Although it is neater that's for sure.
I really was hoping that there would be some kind of VB Script command to do this which would keep the result in a float number and not require the messing with decimal place holder etc.
Thanks anyway, interesting to see how you expert guys would deal with this.
Please feel free to have a look at the linked file (you will see that it works in ANY language) or if anyone is interested enough I will post the full script here.
OK well this is ending up pretty similar to my original script.
If you look at the file I linked to - you would see that the fraction of seconds is required and indeed essential to the calculations.
Also there is the issues with decimal place being different for different languages. So I used the old trick:
Code: Select all
Let>num=0.1
LibFunc>kernel32,GetNumberFormatA,r,0,0,str:num,0,buf,255
MidStr>r_5,2,1,DecimalPlaceHolder
Code: Select all
StringReplace>drate,DecimalPlaceHolder,.,drate
I then ended up using Trunc and Frac to do my final calculations.
So in fact this code is now not much more simple than what I already have. Although it is neater that's for sure.
I really was hoping that there would be some kind of VB Script command to do this which would keep the result in a float number and not require the messing with decimal place holder etc.
Thanks anyway, interesting to see how you expert guys would deal with this.
Please feel free to have a look at the linked file (you will see that it works in ANY language) or if anyone is interested enough I will post the full script here.
Phil Pendlebury - Linktree
Ok Phil... So here's the best I could come up with for a vbscript solution. Also used Separate to break up the decimals even if using a comma. I would guess that much of this could be improved by RegEx but I've yet to attempt RegEx.
What this does is add the seconds quantity onto microsoft's beginning of time giving a result in a date/time format. Then it uses "datediff" between the origin of time and date/time formated "dateadd" result to get the number of hours. It then uses Separate to strip off unwanted garbage. Then we rebuild the string using the hours from datediff.
Step through this in the editor and it will be much clearer than I can explain. In any case this is probably not the easiest solution to your challenge. But it does use VBScript
What this does is add the seconds quantity onto microsoft's beginning of time giving a result in a date/time format. Then it uses "datediff" between the origin of time and date/time formated "dateadd" result to get the number of hours. It then uses Separate to strip off unwanted garbage. Then we rebuild the string using the hours from datediff.
Step through this in the editor and it will be much clearer than I can explain. In any case this is probably not the easiest solution to your challenge. But it does use VBScript
Code: Select all
VBSTART
VBEND
Input>number,Enter number of seconds,1234568,1234
Let>comma=,
Separate>number,comma,cTest
StringReplace>number,comma,.,number
Separate>number,.,nPart
VBEval>DateAdd("s", %nPart_1%, "00:00:00"),res
VBEval>DateDiff("h", #00:00:00#, #%res%#),hourres
Separate>res,:,tItem
Separate>tItem_3, ,seconds
If>nPart_count=1
MDL>%hourres%:%tItem_2%:%seconds_1%
Else
If>%cTest_count%=2
MDL>%hourres%:%tItem_2%:%seconds_1%%comma%%nPart_2%
Else
MDL>%hourres%:%tItem_2%:%seconds_1%.%nPart_2%
EndIf
EndIf
- Phil Pendlebury
- Automation Wizard
- Posts: 543
- Joined: Tue Jan 16, 2007 9:00 am
- Contact:
Thanks JRL. That is very neatly and elegantly done compared to my original rather ugly solution.
Don't forget this wasn't a pleas for help but more a topic of interest and as usual, I have learned a lot from you guys thank you.
Here's my original script btw in case you are interested:
Don't forget this wasn't a pleas for help but more a topic of interest and as usual, I have learned a lot from you guys thank you.
Here's my original script btw in case you are interested:
Code: Select all
Let>RP_ADMIN=1
Let>APP_TITLE=Frame Calculator
Let>MSG_STAYONTOP=1
Let>MSG_CENTERED=1
Let>MSG_WIDTH=360
Let>MSG_HEIGHT=200
Let>WF_TYPE=1
Let>VAREXPLICIT=0
Let>CF_OVERWRITE=1
Let>reg_pattern=[1 or more digits]:[1 or more digits]:[1 or more digits].[1 or more digits]
Let>reg_pattern_text=[letter]
VBSTART
''
VBEND
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//Determine the decimal placeholder
Let>num=0.1
LibFunc>kernel32,GetNumberFormatA,r,0,0,str:num,0,buf,255
MidStr>r_5,2,1,DecimalPlaceHolder
///////////////////////////////////////////////////////////////////////
Dialog>Dialog1
Caption=FR Calc
Width=240
Height=178
Top=CENTER
Left=CENTER
Max=0
Min=0
Close=0
Resize=0
Edit=msEdit2,72,40,73,25
Edit=msEdit1,8,70,137,0
Edit=msEdit3,8,100,137,0:0:0.0
Label=Frame Rate Calc by Phil Pendlebury,10,8,true
Label=Frame Rate:,10,42,true
Button=Calc Frames,152,69,74,23,4,,Calculate Frames from a Time entry and add Frames to clipboard
Button=Calc Time,152,99,74,23,3,,Calculate Time from number of frames and add Time to clipboard
Button=Quit,152,39,74,23,6,,Bye Bye!
MainMenu=Menu,About(30),Help(40),Developers(50),MEAP(60),Quit(6)
EndDialog>Dialog1
///////////////////////////////////////////////////////////////////////
Label>ShowD
Show>Dialog1
Label>DialogLoop
GetDialogAction>Dialog1,res
IF>res=3,calctime
IF>res=4,calcframes
IF>res=6,exit
IF>res=30
MDL>Frame Rate Calculator by Phil Pendlebury%CRLF%%CRLF%Version 2.01 - 16 February 2010
RDA>Dialog1
ENDIF
IF>res=40
MDL>ALWAYS Enter a Frame Rate%CRLF%%CRLF%Enter TOT FRAMES and hit Calc Time to get the time from the number of frames.%CRLF%%CRLF%Enter H:M:S.F and hit Calc Frames to get total frames from that time.
RDA>Dialog1
ENDIF
IF>res=50
MDL>Phil Pendlebury%CRLF%%CRLF%http://www.pendlebury.biz/%CRLF%%CRLF%Thanks to: Fredo, Panos, Bo, Neil
RDA>Dialog1
ENDIF
IF>res=60
ExecuteFile>http://www.meap.biz/
RDA>Dialog1
ENDIF
//
Let>dtotal=%Dialog1.msEdit1%
Let>drate=%Dialog1.msEdit2%
Let>dtime=%Dialog1.msEdit3%
Let>doingtime=3
//
Wait>0.001
GOTO>DialogLoop
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
SRT>calctime
Let>doingtime=1
GOSUB>isnumber
// from frames
StringReplace>drate,DecimalPlaceHolder,.,drate
Let>allframes=%dtotal%
GOSUB>gettimefromsecs
Let>all_time=%chours%:%cminutes%:%cseconds%.%cframes%
Let>Dialog1.msEdit3=%all_time%
PutClipBoard>%all_time%
RDA>Dialog1
END>calctime
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
SRT>calcframes
Let>doingtime=2
GOSUB>sep_time
GOSUB>isnumber
// from time
StringReplace>drate,DecimalPlaceHolder,.,drate
GOSUB>getsecsfromtime
Let>Dialog1.msEdit1=%dtotal%
PutClipBoard>%dtotal%
RDA>Dialog1
END>calcframes
///////////////////////////////////////////////////////////////////////
Label>exit
///////////////////////////////////////////////////////////////////////
SRT>gettimefromsecs
Let>allseconds=allframes/drate
StringReplace>%allseconds%,DecimalPlaceHolder,.,allseconds
////////////////////////////////
let>chours=0
Label>get_hours
IF>allseconds>3599
let>chours=chours+1
let>allseconds=allseconds-3600
StringReplace>%allseconds%,DecimalPlaceHolder,.,allseconds
ENDIF
IF>%allseconds%<3600
GOTO>skip_hours
ENDIF
GOTO>get_hours
Label>skip_hours
////////////////////////////////
let>cminutes=0
Label>get_minutes
IF>allseconds>59
let>cminutes=cminutes+1
let>allseconds=allseconds-60
StringReplace>%allseconds%,DecimalPlaceHolder,.,allseconds
ENDIF
IF>%allseconds%<60
GOTO>skipminutes
ENDIF
GOTO>get_minutes
Label>skipminutes
////////////////////////////////
Let>cseconds={Trunc(%allseconds%)}
Let>fracseconds={Frac(%allseconds%)}
StringReplace>%fracseconds%,DecimalPlaceHolder,.,fracseconds
Let>fracframes=fracseconds*drate
StringReplace>%fracframes%,DecimalPlaceHolder,.,fracframes
Let>cframes=%fracframes%
// Round to 6 DP
VBEval>Round(%cframes%,10),cframes
// MidStr>%cframes%,1,10,cframes
////////////////////////////////
// MDL> HOUR: %chours% MIN: %cminutes% SEC: %cseconds% FR: %cframes%
END>gettimefromsecs
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
SRT>getsecsfromtime
//
Let>fhours=%dhours%*60
Let>fhours=%fhours%*60
Let>fhours=%fhours%*%drate%
//
Let>fminutes=%dminutes%*60
Let>fminutes=%fminutes%*%drate%
//
Let>fseconds=%dseconds%*%drate%
//
Let>dtotal=%fhours%+%fminutes%
Let>dtotal=%dtotal%+%fseconds%
Let>dtotal=%dtotal%+%dframes%
//
// MDL>Total Frames: %dtotal%
END>getsecsfromtime
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
SRT>sep_time
//
Separate>dtime,:,sep_hms
Separate>sep_hms_3,.,sep_frm
Let>dhours=%sep_hms_1%
Let>dminutes=%sep_hms_2%
Let>dseconds=%sep_frm_1%
Let>dframes=%sep_frm_2%
END>sep_time
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
SRT>isnumber
IF>%drate%>0
Let>check_drate=%drate%/%drate%
IF>check_drate<>1
Let>error=FRAME RATE
GOSUB>reset
ENDIF
ELSE
IF>%drate%=0
MDL>Frame Rate must be something other than Zero!
RDA>Dialog1
GOTO>DialogLoop
ENDIF
ENDIF
IF>%drate%=
MDL>Frame Rate must contain a value!
RDA>Dialog1
GOTO>DialogLoop
ENDIF
IF>doingtime=1
IF>%dtotal%=
MDL>Frames must contain a value!
RDA>Dialog1
GOTO>DialogLoop
ENDIF
IF>%dtotal%>0
Let>check_dtotal=%dtotal%/%dtotal%
IF>check_dtotal<>1
Let>error=FRAMES
GOSUB>reset
ENDIF
ELSE
MDL>Frames must contain a value greater than Zero!
ENDIF
ENDIF
IF>doingtime=2
IF>%dtime%=
MDL>Time must contain a value!
RDA>Dialog1
GOTO>DialogLoop
ENDIF
IF>%dtime%=0:0:0.0
MDL>Time must contain a value greater than Zero!
ENDIF
IF>%dtime%>0
RegEx>reg_pattern_text,dtime,1,tmatches,tnum,0
IF>tnum>0
MDL>Time Must not contain letters!
RDA>Dialog1
GOTO>DialogLoop
ENDIF
RegEx>reg_pattern,dtime,1,matches,num,0
IF>num<1
MDL>Time Must be in format H:M:S.F (0:0:0.0)
RDA>Dialog1
GOTO>DialogLoop
ENDIF
ENDIF
ENDIF
END>isnumber
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
SRT>reset
MDL>%error% contains a value that isn't a number!
RDA>Dialog1
GOTO>DialogLoop
END>reset
///////////////////////////////////////////////////////////////////////
Phil Pendlebury - Linktree
Including Commas in variable Number
Hi Forum,
I am interesting in seeing the commas in a number when it is displayed in a dialog or message box. Is there a straightforward approach e.g., a format function?
Here is a snippet of my code:
Random>5000000,r
Let num=100000+r
MessageModal>num
The variable 'num' is displayed without any commas.
Thanks
I am interesting in seeing the commas in a number when it is displayed in a dialog or message box. Is there a straightforward approach e.g., a format function?
Here is a snippet of my code:
Random>5000000,r
Let num=100000+r
MessageModal>num
The variable 'num' is displayed without any commas.
Thanks
I hope this helps...
Code: Select all
VBSTART
VBEND
Random>5000000,r
Let>num=100000+r
VBEval>FormatNumber(%num%,0),DisplayNumber
MessageModal>DisplayNumber