Problems format time in VBA - vba

I have a big problem with formats.
When VBA write a number (Time() - actualtime) the result is in seconds, but excel thinks that is days!
so, when i put this command:
Selection.NumberFormat = "[h]:mm:ss.00" the seconds are days!
A solution is adding /(24*3600) but this is give me an error, perhaps because it is a really small number.
ActiveCell = ((Timer() - startTime) where starttime is a Timer() define some time back.

Try
Timeserial(0,0,Time() - actualtime)
Timeserial will return a time value, and putting the value you want in the "seconds" argument will ensure the number returned is treated correctly.
Let me know if this helps!

It's due to the type conversion. Because 3600 and 24 are both integers, the result of multiplying them are converted to a 16 bit Int. A 16 bit Int has a range of -32768 to +32767
You can see this by running the following line which does not give an error and returns back 32767
MsgBox 32766 + 1
Whereas the below line fails with an overflow error due to it exceeding the maximum value.
MsgBox 32766 + 2
As it has already been mentioned, you can circumvent this by dividing the values separately
(Time() - actualtime) / 3600 / 24 will work..
Also, you can tell excel that you want to use a different type,
MsgBox (Time() - actualtime) / (24# * 3600) 'use Double
MsgBox (Time() - actualtime) / (24& * 3600) 'use Long
The hash or ampersand after the 24 tells excel that you want the value to be used as a defined type and these statements won't fail with an overflow error.

Fascinating.
actualtime / (24 * 3600)
produces an overflow error in VBA.
actualtime / 24 / 3600
does not.
Something about multiplying 24 and 3600 produces an overflow error.

Related

Arithmetic overflow error converting expression to data type date time

I am trying to get days difference between 2 days and I am getting below error.
Could any one please help
CONVERT(DECIMAL,((dbo.convertToUnixTime(GETDATE())-p.CREATEDDATE)))
Msg 8115, Level 16, State 2, Line 79
Arithmetic overflow error converting expression to data type datetime.
If you want fractional days, then you can take the difference in another unit, say seconds, and divide:
SELECT DATEDIFF(second, p.CREATEDATE, GETDATE()) / (24.0 * 60 * 60)
Note that for DATEDIFF() the older date goes first. I assume p.CREATEDATE is in the past and you want a positive number.
If you are dealing with dates far in the past or the future, you might want to use minute rather than second or alternatively DATEDIFF_BIG().
Use the date functions:
SELECT DATEDIFF(day,GETDATE(),p.CREATEDATE)
datediff() always return an integer value, expressed in the unit your are giving as first argument.
If you want something accurate, you can compute the date difference in seconds, then use artithmetics to convert to a number of days:
datediff(second, p.createdate, getdate()) / 60.0 / 60 / 24

Values vary after conversion from excel

I am trying to get values from one of the column from excel and i am facing strange issue that i cannot overcome so far.
Excel cells text we working on
Column format is set to: [h]:mm:ss so means hours could exceed 12/24.
When i am getting that values they are in double format as excel probbaly stores it in that way therefore i decided to write function to convert it back again to hours, minutes and seconds so i did that function:
Public Shared Function parseExcelHour(cellInput As String) As String
Dim excelHour As Double = 0
Dim hour As Integer
Dim min As Integer
Dim sec As Integer
Try
excelHour = [Double].Parse(cellInput)
Catch
End Try
sec = CInt((excelHour * 1440 * 60) Mod 60)
min = CInt((excelHour * 1440) Mod 60)
'mod (%) takes only the remainder as an int (if 5/4 = 1.25 , % only takes the number 1 that cannot be divided into an integer)
hour = CInt((excelHour * 1440) / 60)
' with the int cast you get only an integer.
Return hour & ":" & min & ":" & sec
End Function
However when i see the results, they are vary between excel and what i get after conversion. For three of them hours are either -1 or +1 if you compare. Also in one case we have additional + 1 minute. I suppose there is wrong hour calculation but i could be in wrong. See on screeshoot:
Results
Does anyone knows why i got those differences? Is that because i am missing something within my method or something else.
Excel stores a full Datetime equivalent as one double. The part before the decimal point is the days (since 1.1.1900; 1.1.1904 on Mac; note the bug that 1900 is faultily cosnider a leap year in Excel).
The part after is the time of the day, wich is what you apparently want:
https://stackoverflow.com/a/981865/3346583
What you are seeing in excel is meerely a ToString Foramting of the double value. Same way DateTime.ToString() would give you a string representation of whatever value is actually stored (most often a realy big unsigned int, with the ticks since a date).
A difference in full hours sounds like it might be a Timezone issue. But I am not aware that Excel stores Timezones in the first place (or what default timezone it asumes).

24hr time format string to sql time format

We have a column that stores a value in 24 hr time format. It is a string/text that users enter on to the interface. I need to convert it into sql time format so that I can do time difference calculations. How can I convert the string to time? Example:
StringColumn
1400
1600
needs to be
TimeColumn
1400
1600
so that I can calculate the time difference to get 2 hrs. Thanks.
If your string value are always 4 characters (meaning 01-09 and not 1-9 for early hours) then this works:
convert(time, stuff(StringColumn,3,0,':'))
You can do a conversion as in #jpw's answer, especially if you can use DATEDIFF on the results to get what you need.
Alternately you could perhaps do it as integer maths like:
SELECT (60*left('1900',2) + right('1900',2)) - (60*left('1400',2) + right('1400',2))
(I have used constants here, but you can replace '1900' and '1400' with column names).
CAST(LEFT(Stringcolumn, 2) + ':' + RIGHT(LEFT(Stringcolumn, 4), 2) AS TIME)

Convert Float value to Hours and Minutes

I have a float value, for example 0.999888, which I am getting from SQL database.
I have a variable in vbscript assigned to the float value from the SQL.
Lets say that I have this, for example
Dim TimeInFloat
TimeInFloat = 0.999888
I want to convert it to the hours and minutes either in SQL itself or VBscript.
Any suggestions?
You can convert it to hours and minutes in SQL by doing:
select floor(TimeInFloat * 24) as hours,
60 * (TimeInFloat * 24 - floor(TimeInFloat * 24)) as minutes
You can do similar logic in VBA.
In VBScript the CDate function allows you to convert float/double to time:
>>> WScript.Echo CDate(0.999888)
23:59:50

How do I calculate hours when there are fractional components

I am trying to make a spreadsheet to calculate my hours for the week. The problem I am having is the DateDiff function only returns integers so I am getting incorrect results.
Function CalculateHoursDay(strStart As String, strEnd As String, intLunch As Integer) As Double
Dim dblHours As Double
dblHours = DateDiff("h", strStart, DateAdd("h", 12, strEnd)) - intLunch
CalculateHoursDay = dblHours
End Function
If I call the function with "7:00", "2:45", .5 then I get 7 back when I need 7.25. In fact I get 7 also for "7:00", "2:45", 0 so you can see the decimal value is getting truncated. I add 12 hours so times can be easily entered without regard for AM, PM or military time since over 99% (if not 100%) of the time the times will be AM for start time and PM for end time.
I am expecting to get 7.25 from the function with the stated parameters. Any suggestions?
Alex provided the correct answer and tbur also pointed out a bug that would've surfaced as soon as I applied Alex's solution.
Function CalculateHoursDay(strStart As String, strEnd As String, dblLunch As Double) As Double
Dim dblHours As Double
'"n" refers to minutes.
dblHours = (DateDiff("n", strStart, DateAdd("h", 12, strEnd)) / 60) - dblLunch
CalculateHoursDay = dblHours
End Function