Convert Seconds to YmdHms

Started by jtrask, October 15, 2015, 11:05:20 AM

Previous topic - Next topic

jtrask

Before I successfully re-invent the wheel (I'm failing miserably at present), is there a prescribed method for converting seconds to YmdHms or some other recognizable time format?

I thought I had a grip in it, but I've got what must be a rounding error.  I experiencing a discrepancy of 4 hours for a 13 day 21ish hour elapsed time.

At first that seemed crazy to me, but I AM doing some crazy math.  I'm using the Huge Math Extender and converting seconds to minutes.  Then I convert the minutes to years.  I take what's to the left of my decimal as the years, and take what's on the right to be months.  Then I do more math to calculate months/fractions of a month.  Then I turn the fraction of a month into days, etc.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                               
; UDF_SecMinToYmdHms()
; Version 1.0                                             
;                                                                                                               
; Decription: Converts seconds or minutes to YmdHms format
;
; Dependencies:
;
; Global Variables:
;
; Inputs: vintElapsed = Number of seconds or minutes to convert
;         vintUOM = Unit of measure.  Either "Seconds" or "Minutes"
;
; Outputs: Elapsed time in YmdHms format
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#DefineFunction UDF_SecMinToYmdHms(vintElapsed,vstrUOM)

; Set the program to goto the WBErrorHandler function if there is a problem.
IntControl(73,3,0,"UDF_WBErrorHandler",0)

; Resume DebugTrace (if it was already active
DebugTrace(22)

Huge_Decimal(20)

vintElapsed = Huge_Multiply(vintElapsed,1) ;convert to a huge number

If StriCmp(vstrUOM,"Seconds") == 0 Then
vintElapsedMinutes = Huge_Divide(vintElapsed,60)
Else
vintElapsedMinutes = Huge_Multiply(vintElapsedMinutes,1)
End If

vintYears = Huge_Divide(vintElapsedMinutes,525600) ; Minutes in a year
vintTempMonths = ".":ItemExtract(2,vintYears,".")
vintYears = ItemExtract(1,vintYears,".")

vintMonths = Huge_Multiply(vintTempMonths,12) ; 12 = months in a year
vintTempDays = ".":ItemExtract(2,vintMonths,".")
vintMonths = ItemExtract(1,vintMonths,".")

vintDays = Huge_Multiply(vintTempDays,30) ; 30 = days in a month (roughly)
vintTempHours = ".":ItemExtract(2,vintDays,".")
vintDays = ItemExtract(1,vintDays,".")

vintHours = Huge_Multiply(vintTempHours,24) ; 24 = hours in a day
vintTempMinutes = ".":ItemExtract(2,vintHours,".")
vintHours = ItemExtract(1,vintHours,".")

vintMinutes = Huge_Multiply(vintTempMinutes,60) ; 60 = minutes in an hour
vintTempSeconds = ".":ItemExtract(2,vintMinutes,".")
vintMinutes = ItemExtract(1,vintMinutes,".")

vintSeconds = vintTempSeconds * 60 ; 60
vintSeconds = vintSeconds * 1.0
vintSeconds = ItemExtract(1,vintSeconds,".")

vstrElapsed = vintYears:":":vintMonths:":":vintDays:":":vintHours:":":vintMinutes:":":vintSeconds

Return(vstrElapsed)

#EndFunction






; Huge Math Extender for converting seconds to YmdHms
AddExtender("WWHUG44I.dll",0,"WWHUG64I.dll")

vintElapsed = UDF_SecMinToYmdHms(1198800,"Seconds")

JTaylor

No time to try it at the moment but could you just use TimeAdd()?   Not sure if it would work if it is a HUGE number but a thought.    Maybe divide the HUGE number into one TimeAdd would recognize if needed?   Starting point would be one of the questions I suppose.

Jim

JTaylor

Something like:

Code (winbatch) Select


start_time       = "1000:01:01:00:00:00"
time_in_seconds  = "92387812"

dateo = TimeAdd(start_time,"0000:00:00:00:00:":time_in_seconds)

amt_of_time = TimeDiff(dateo,start_time)

message(dateo, amt_of_time)


or the combined version

Code (winbatch) Select


time_in_seconds  = "92387812"

amt_of_time = TimeDiff(TimeAdd("1000:01:01:00:00:00","0000:00:00:00:00:":time_in_seconds),"1000:01:01:00:00:00")





jtrask

It gets upset when I pass it 119880 seconds. 

Perhaps I can fiddle with the number and convert it to larger units of measure and then use TimeDiff/TimeAdd?

jtrask

Actually, I fat fingered my number of seconds when I copied it into the script.  I THOUGH I was converting 1198800 seconds, but I was, in fact, converting 119880 seconds. Big difference.

JTaylor, you are a genius.  This is soooo much simpler.  And it has an added bonus: it WORKS!


JTaylor


td

Just remember that the time_in_seconds variable cannot contain an integer equivalent value larger than 2147483647. Which works out to a little over 68 years worth of seconds...
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

Yeah, that is why I suggested using HUGE Math to divide it if needed.  Looks like his number of seconds is fairly small though if what is posted is a standard sample.

Jim

td

Quote from: JTaylor on October 15, 2015, 02:58:49 PM
Yeah, that is why I suggested using HUGE Math to divide it if needed.  Looks like his number of seconds is fairly small though if what is posted is a standard sample.

Jim

Just noting the limit for future readers since it's not documented anywhere.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

.NET has TimeSpan - could that be used with the WB CLR?

td

It's a structure so you would have write a C# wrapper class and it has the same seconds limit as TimeAdd.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

DAG_P6

Quote from: stanl on October 17, 2015, 04:19:02 AM
.NET has TimeSpan - could that be used with the WB CLR?

Only if you used its Ticks member, which is a 64 bit integer. Owing to its simplicity, I use the Ticks member for most of the arithmetic I do with times in .NET.
David A. Gray
You are more important than any technology.