In my code I want to record the amount of seconds passed. I was using Second(Now) to measure how much time has passed since a point and used the integer in comparisons but have realised that if the minute ends, it goes to zero. This led me to add in Minute(Now) so that I could multiply this by 60 then add on Second(Now) but there is a similar problem of this number becoming zero once the hour passes.
What can I use instead of this to record the amount of seconds elapsed after a certain time.
You can use a TimeSpan to register the difference between two Now DateTime by using the DateTime.substract method. here is an illustration. Only after the operation do we convert the elapsed time into the unit we desire to use (for example seconds in our case)
Static start_time As DateTime
Static stop_time As DateTime
Dim elapsed_time As TimeSpan
start_time = Now
''' Processing here
stop_time = Now
elapsed_time = stop_time.Subtract(start_time)
Dim totalSecondsStr = elapsed_time.TotalSeconds.ToString("0.000000")
Related
In Visual Basic .NET, I am trying to convert time elapsed in seconds to hh:mm:ss format which can go over 24 hours.
As an example, when try to convert 86400 seconds to a timespan with the following code:
dim sec = 86400
dim res = TimeSpan.FromSeconds(sec).ToString
the output is "1.00:00:00"
while the desired output for me is "24:00:00"
How is it possible to do so?
You just need to do the calculation:
Dim secs = 86400
Dim ts = TimeSpan.FromSeconds(secs)
Dim res = String.Format("{0}:{1:00}:{2:00}", (ts.Days * 24 + ts.Hours), ts.Minutes, ts.Seconds)
Console.WriteLine(res)
Outputs:
24:00:00
If you want at least two digits for the hours, use "{0:00}:{1:00}:{2:00}".
(You could use String.Format("{0}:{1:00}:{2:00}", Math.Floor(ts.TotalHours), ts.Minutes, ts.Seconds) if you think it looks better.)
What you ask isn't available either as a standard or custom format.
You want to emit the total hours as a rounded-down integer followed by the minutes and seconds part. The custom format specifiers only work for specific parts.
You can use the TimeSpan.TotalHours property to retrieve the hours as a double and format the rest of the string using custom specifiers.
Dim ts=TimeSpan.FromDays(1)
String.Format("{0:00}:{1:mm\:ss}",Math.Floor(ts.TotalHours), ts)
Or
Dim ts=TimeSpan.FromSeconds(61)
String.Format("{0:00}:{1:mm\:ss}",Math.Floor(ts.TotalHours), ts)
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).
I am having an OData Service returning some DateTime values. They are saved in a table in the back end as TIMESTAMPL (with some other data).
Now there is the value 20160630084459.5000. With MOVE-CORRESPONDING into the et_entityset, where it is a TIMESTAMP. Because of the rounding, it gets 20160630084460, Since a the seconds must be between 00 and 59, this is not a valid value to return.
My main problem is, that my table has extremely much entries, so I need a performant way to fix this error.
Here is a way to convert it to what you want.
REPORT zzy NO STANDARD PAGE HEADING.
FORM convert_timestamp.
DATA(l_t1) = CONV timestampl('20160630084459.5000').
DATA: l_t2 TYPE timestamp.
l_t2 = l_t1.
WRITE / : l_t1, l_t2.
CONVERT TIME STAMP l_t1 TIME ZONE sy-zonlo INTO DATE DATA(l_date) TIME DATA(l_time).
CONVERT DATE l_date TIME l_time INTO TIME STAMP l_t2 TIME ZONE sy-zonlo.
WRITE / l_t2.
ENDFORM.
START-OF-SELECTION.
PERFORM convert_timestamp.
Here is the output.
20.160.630.084.459,5000000
20.160.630.084.460
20.160.630.084.459
You mention floor in your question but that is not what is happening. The value is rounded. If you simple do use FLOOR in your assignment from TIMESTAMPL to TIMESTAMP you will get the answer you want. If you have to use MOVE-CORRESPONDING, just do that first and then do a seperate assignment for the timestamp.
However, this means that 0:59.9 will get translated to 0:59 and not 1:00. If that missing second is OK for your application then just use the FLOOR command. If not it becomes more complicated and you will take a performance hit.
Consider this:
Dim n as Long
n = Now
Why does this give you tomorrow after midday?
It's because Now returns a double to represent the time of day as well as the day itself. The fractional part is used to model the time of day and at noon that value is exactly one half.
Also, the implicit cast to Long rounds the value. This is unlike the casts of c and c++ which truncate the fractional part.
You could use Fix(Now) to truncate.
I'm working on a problem where I need to determine the total time my program takes to execute. First line of code needs to write the current "Start time" and last lines of code need to write the current "End time". Then I'm subtracting "Start time" - "End Time" = Total Time.
I'm confused how I would use the FORMAT() function within VBA on the value of C2 to convert into seconds? Is there an other function that would work better than FORMAT? Basically I'm confused about Excel's Date Serial values and what they represent.
Code is below
EDIT: Thanks for the responses everyone. Both answers below work for what I'm trying to do.
sub ExecutionTime()
Worksheets("Table").Range("A2").Value = Now()
'All my executable code goes here. It's a relatively small program compiling a table so it
runs very quick.
Worksheets("Table").Range("B2").Value = Now()
Worksheets("Table").Range("C2").Value = Worksheets("Table").Range("A2").Value - Worksheets("Table").Range("B2").Value
end Sub
Do not use a Date data member or the Now method to analyze run time of your program. Instead, the Timer function is the most appropriate solution as it returns a Single representing seconds. It will require no type conversion and yields a more accurate result than an integer amount of seconds.
Using LimaNightHawk's answer as a template as you should be storing these in local variables instead of writing directly to the worksheet.
Dim startTime as Single
startTime = Timer()
' Do stuff
Dim endTime as Single
endTime = Timer()
Dim runTime as Single
runTime = endTime - startTime
Results should be written at the end of the routine.
With Worksheets("Table")
.Range("A2").Value = startTime
.Range("B2").Value = endTime
.Range("C2").Value = runTime
End With
Documentation on the timer function
In the first line of your program get the date (no need to format):
Dim startTime as Date
startTime = Now()
At the end of your program, get the date again:
Dim endTime as Date
endTime = Now()
Then use the DateDiff
Dim timeInSeconds as long
timeInSeconds = DateDiff("s", startTime, endTime)
DateDiff() is what you are looking for. The "s" defines that you are looking for the difference in seconds.
Worksheets("Table").Range("C2").Value = DateDiff("s", Worksheets("Table").Range("A2").Value, Worksheets("Table").Range("B2").Value)
EDIT: http://www.likeoffice.com/28057/excel-date to learn more about working with dates and times in Excel VBA. It is important to understand that dates work differently within the context of VBA, and have their own unique set of syntax functions for manipulating.
2nd EDIT: A cleaner version of this would be:
StartDateTime = Now()
'Run Code
Worksheets("Table").Range("C2").Value = DateDiff("s", StartDateTime, Now())
There's a few ways you can use VBA to format cells / variables.
In no particular order, firstly you can format ranges with the NumberFormat property which can be applied like so:
Worksheets("Table").Range("C2").Value = Now()
Worksheets("Table").Range("C2").NumberFormat = "ss"
The other way is that you could format Now() using the Format() function:
Worksheets("Table").Range("C2").Value = Format(Now(), "ss")
See the documentation from Microsoft to implement different formats:
NumberFormat: http://msdn.microsoft.com/en-us/library/office/ff196401%28v=office.15%29.aspx
Format: http://msdn.microsoft.com/en-us/library/office/gg251755%28v=office.15%29.aspx
How i generally go about bragging my process time to user
Sub Process()
Dim startTime as Date
Dim endTime as Date
startTime = Now
'Logic for what your process must do
endTime = Now
MsgBox "Process completed in : " & Format(endTime - startTime, "hh:mm:ss")
End Sub