Convert integer to full text string durationMilliseconds to Time string & Time string to...
How frequently do Russian people still refer to others by their patronymic (отчество)?
Sleepy tired vs physically tired
Can a USB hub be used to access a drive from 2 devices?
Shipped package arrived - didn't order, possible scam?
Are "confidant" and "confident" homophones?
Do I need to be legally qualified to install a Hive smart thermostat?
Isn't "Dave's protocol" good if only the database, and not the code, is leaked?
Initializing variables variable in an "if" statement
Will electrically joined dipoles of different lengths, at right angles, behave as a multiband antenna?
How can select a specific triangle in my Delaunay mesh?
How can I effectively map a multi-level dungeon?
Was I wrongfully denied boarding for having a Schengen visa issued from the second country on my itinerary?
How did the IEC decide to create kibibytes?
Is there a standard definition of the "stall" phenomena?
Why would "dead languages" be the only languages that spells could be written in?
LTSpice: how to setup sinusoidal or exponential voltage source?
What instances can be solved today by modern solvers (pure LP)?
What's the difference between a type and a kind?
Is it possible to spoof an IP address to an exact number?
Why weren't Gemini capsules given names?
Is there a way to change the aspect ratio of a DNG file?
Does 5e have an equivalent of the Psychic Paper from Doctor Who?
Why do we need a bootloader separate from our application program in microcontrollers?
Did Stalin kill all Soviet officers involved in the Winter War?
Convert integer to full text string duration
Milliseconds to Time string & Time string to MillisecondsConvert string to multiline textConvert number into hours : minutesClassifying duration as <1, 1-2, 2-3, or >3 yearsConvert Integer to Date in JavaFilter to convert duration to hours — in controller or model?Convert Iterable tree to stringConvert Lua UINT to hh:mm:ssConvert decimal to stringConvert integer to decimal string
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
$begingroup$
I have a function I have written in VB for use in SSRS 2012. It takes an integer and converts it to full text duration - for example 900 becomes "15 minutes", 9000 becomes "2 hours 30 minutes", and 7201 is "2 hours 1 second".
The code works, and is:
Public Function SecondsFullText(ByVal TotalSeconds As Integer) As String
Dim hours As Integer = new Integer()
Dim minutes As Integer = new Integer()
Dim seconds As Integer = new Integer()
Dim hourString as String = ""
Dim minuteString as String = ""
Dim secondString as String = ""
hours = floor(TotalSeconds / 3600)
minutes = floor((TotalSeconds mod 3600) / 60)
seconds = (TotalSeconds mod 3600) mod 60
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
If minutes = 1 Then
minuteString = Cstr(minutes) & " minute"
Else If minutes > 1 Then
minuteString = Cstr(minutes) & " minutes"
End If
If seconds = 1 Then
secondString = Cstr(seconds) & " second"
Else If seconds > 1 Then
secondString = Cstr(seconds) & " seconds"
End If
If hours > 0 and (minutes > 0 or seconds > 0) Then
hourString = hourString & " "
End If
If minutes > 0 and seconds > 0 Then
minuteString = minuteString & " "
End If
return hourString & minuteString & secondString
End Function
My question is: how do I make this better? It seems very clunky, with too many IFs to handle the different possibilities for single/plural, spaces, etc. I feel that this can be better, but I'm not sure how.
This is called in Report Builder 3.0 / SSRS 2012 with this expression: =Code.SecondsFullText(Parameters!Integer.Value)
datetime formatting vb.net
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
I have a function I have written in VB for use in SSRS 2012. It takes an integer and converts it to full text duration - for example 900 becomes "15 minutes", 9000 becomes "2 hours 30 minutes", and 7201 is "2 hours 1 second".
The code works, and is:
Public Function SecondsFullText(ByVal TotalSeconds As Integer) As String
Dim hours As Integer = new Integer()
Dim minutes As Integer = new Integer()
Dim seconds As Integer = new Integer()
Dim hourString as String = ""
Dim minuteString as String = ""
Dim secondString as String = ""
hours = floor(TotalSeconds / 3600)
minutes = floor((TotalSeconds mod 3600) / 60)
seconds = (TotalSeconds mod 3600) mod 60
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
If minutes = 1 Then
minuteString = Cstr(minutes) & " minute"
Else If minutes > 1 Then
minuteString = Cstr(minutes) & " minutes"
End If
If seconds = 1 Then
secondString = Cstr(seconds) & " second"
Else If seconds > 1 Then
secondString = Cstr(seconds) & " seconds"
End If
If hours > 0 and (minutes > 0 or seconds > 0) Then
hourString = hourString & " "
End If
If minutes > 0 and seconds > 0 Then
minuteString = minuteString & " "
End If
return hourString & minuteString & secondString
End Function
My question is: how do I make this better? It seems very clunky, with too many IFs to handle the different possibilities for single/plural, spaces, etc. I feel that this can be better, but I'm not sure how.
This is called in Report Builder 3.0 / SSRS 2012 with this expression: =Code.SecondsFullText(Parameters!Integer.Value)
datetime formatting vb.net
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
$begingroup$
It would be easier to provide a review and answer if the function that called this or displayed the resulting string was included as well.
$endgroup$
– pacmaninbw
10 hours ago
$begingroup$
@pacmaninbw Noted, and updated. There's no real function that calls it as it's for use in a report in SSRS.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
I did this as a one-liner in groovy for fun--converted milliseconds to something like 1d2h3m10s. I don't think I have the one-liner any more but I converted it into 4 significantly more readable lines you're welcome to if you want them :) (Now it's part of Java so I don't really need it any more, you can have it)
$endgroup$
– Bill K
2 hours ago
$begingroup$
Code aside, "an integer" has no units and cannot be converted to a string representation of time with additionally specifying units. So you don't just have an integer; you have an integer number of seconds. You need to be more careful about this in your documentation and communication.
$endgroup$
– jpmc26
2 hours ago
add a comment |
$begingroup$
I have a function I have written in VB for use in SSRS 2012. It takes an integer and converts it to full text duration - for example 900 becomes "15 minutes", 9000 becomes "2 hours 30 minutes", and 7201 is "2 hours 1 second".
The code works, and is:
Public Function SecondsFullText(ByVal TotalSeconds As Integer) As String
Dim hours As Integer = new Integer()
Dim minutes As Integer = new Integer()
Dim seconds As Integer = new Integer()
Dim hourString as String = ""
Dim minuteString as String = ""
Dim secondString as String = ""
hours = floor(TotalSeconds / 3600)
minutes = floor((TotalSeconds mod 3600) / 60)
seconds = (TotalSeconds mod 3600) mod 60
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
If minutes = 1 Then
minuteString = Cstr(minutes) & " minute"
Else If minutes > 1 Then
minuteString = Cstr(minutes) & " minutes"
End If
If seconds = 1 Then
secondString = Cstr(seconds) & " second"
Else If seconds > 1 Then
secondString = Cstr(seconds) & " seconds"
End If
If hours > 0 and (minutes > 0 or seconds > 0) Then
hourString = hourString & " "
End If
If minutes > 0 and seconds > 0 Then
minuteString = minuteString & " "
End If
return hourString & minuteString & secondString
End Function
My question is: how do I make this better? It seems very clunky, with too many IFs to handle the different possibilities for single/plural, spaces, etc. I feel that this can be better, but I'm not sure how.
This is called in Report Builder 3.0 / SSRS 2012 with this expression: =Code.SecondsFullText(Parameters!Integer.Value)
datetime formatting vb.net
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
I have a function I have written in VB for use in SSRS 2012. It takes an integer and converts it to full text duration - for example 900 becomes "15 minutes", 9000 becomes "2 hours 30 minutes", and 7201 is "2 hours 1 second".
The code works, and is:
Public Function SecondsFullText(ByVal TotalSeconds As Integer) As String
Dim hours As Integer = new Integer()
Dim minutes As Integer = new Integer()
Dim seconds As Integer = new Integer()
Dim hourString as String = ""
Dim minuteString as String = ""
Dim secondString as String = ""
hours = floor(TotalSeconds / 3600)
minutes = floor((TotalSeconds mod 3600) / 60)
seconds = (TotalSeconds mod 3600) mod 60
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
If minutes = 1 Then
minuteString = Cstr(minutes) & " minute"
Else If minutes > 1 Then
minuteString = Cstr(minutes) & " minutes"
End If
If seconds = 1 Then
secondString = Cstr(seconds) & " second"
Else If seconds > 1 Then
secondString = Cstr(seconds) & " seconds"
End If
If hours > 0 and (minutes > 0 or seconds > 0) Then
hourString = hourString & " "
End If
If minutes > 0 and seconds > 0 Then
minuteString = minuteString & " "
End If
return hourString & minuteString & secondString
End Function
My question is: how do I make this better? It seems very clunky, with too many IFs to handle the different possibilities for single/plural, spaces, etc. I feel that this can be better, but I'm not sure how.
This is called in Report Builder 3.0 / SSRS 2012 with this expression: =Code.SecondsFullText(Parameters!Integer.Value)
datetime formatting vb.net
datetime formatting vb.net
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 6 hours ago
200_success
134k21 gold badges170 silver badges440 bronze badges
134k21 gold badges170 silver badges440 bronze badges
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 11 hours ago
BishNaboBBishNaboB
1285 bronze badges
1285 bronze badges
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
BishNaboB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$begingroup$
It would be easier to provide a review and answer if the function that called this or displayed the resulting string was included as well.
$endgroup$
– pacmaninbw
10 hours ago
$begingroup$
@pacmaninbw Noted, and updated. There's no real function that calls it as it's for use in a report in SSRS.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
I did this as a one-liner in groovy for fun--converted milliseconds to something like 1d2h3m10s. I don't think I have the one-liner any more but I converted it into 4 significantly more readable lines you're welcome to if you want them :) (Now it's part of Java so I don't really need it any more, you can have it)
$endgroup$
– Bill K
2 hours ago
$begingroup$
Code aside, "an integer" has no units and cannot be converted to a string representation of time with additionally specifying units. So you don't just have an integer; you have an integer number of seconds. You need to be more careful about this in your documentation and communication.
$endgroup$
– jpmc26
2 hours ago
add a comment |
$begingroup$
It would be easier to provide a review and answer if the function that called this or displayed the resulting string was included as well.
$endgroup$
– pacmaninbw
10 hours ago
$begingroup$
@pacmaninbw Noted, and updated. There's no real function that calls it as it's for use in a report in SSRS.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
I did this as a one-liner in groovy for fun--converted milliseconds to something like 1d2h3m10s. I don't think I have the one-liner any more but I converted it into 4 significantly more readable lines you're welcome to if you want them :) (Now it's part of Java so I don't really need it any more, you can have it)
$endgroup$
– Bill K
2 hours ago
$begingroup$
Code aside, "an integer" has no units and cannot be converted to a string representation of time with additionally specifying units. So you don't just have an integer; you have an integer number of seconds. You need to be more careful about this in your documentation and communication.
$endgroup$
– jpmc26
2 hours ago
$begingroup$
It would be easier to provide a review and answer if the function that called this or displayed the resulting string was included as well.
$endgroup$
– pacmaninbw
10 hours ago
$begingroup$
It would be easier to provide a review and answer if the function that called this or displayed the resulting string was included as well.
$endgroup$
– pacmaninbw
10 hours ago
$begingroup$
@pacmaninbw Noted, and updated. There's no real function that calls it as it's for use in a report in SSRS.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
@pacmaninbw Noted, and updated. There's no real function that calls it as it's for use in a report in SSRS.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
I did this as a one-liner in groovy for fun--converted milliseconds to something like 1d2h3m10s. I don't think I have the one-liner any more but I converted it into 4 significantly more readable lines you're welcome to if you want them :) (Now it's part of Java so I don't really need it any more, you can have it)
$endgroup$
– Bill K
2 hours ago
$begingroup$
I did this as a one-liner in groovy for fun--converted milliseconds to something like 1d2h3m10s. I don't think I have the one-liner any more but I converted it into 4 significantly more readable lines you're welcome to if you want them :) (Now it's part of Java so I don't really need it any more, you can have it)
$endgroup$
– Bill K
2 hours ago
$begingroup$
Code aside, "an integer" has no units and cannot be converted to a string representation of time with additionally specifying units. So you don't just have an integer; you have an integer number of seconds. You need to be more careful about this in your documentation and communication.
$endgroup$
– jpmc26
2 hours ago
$begingroup$
Code aside, "an integer" has no units and cannot be converted to a string representation of time with additionally specifying units. So you don't just have an integer; you have an integer number of seconds. You need to be more careful about this in your documentation and communication.
$endgroup$
– jpmc26
2 hours ago
add a comment |
3 Answers
3
active
oldest
votes
$begingroup$
You should look into the TimeSpan struct, which provides a nice method TimeSpan.FromSeconds().
Having filled a TimeSpan struct by e.g calling the FromSeconds() method, you can just access its properties Seconds, Minutes and Hours.
Instead of concating strings like you do, you should consider to use a StringBuilder.
To get rid of the If ... Else If you can just use the singular and only if the value is greater than 1 you add a s to the string/StringBuilder.
Based on the .NET Naming Guidelines method parameters should be named using camelCase casing hence TotalSeconds should be totalSeconds
Implementing the mentioned points will look like so
Public Function SecondsFullText(ByVal totalSeconds As Double) As String
Dim timeSpan As TimeSpan = TimeSpan.FromSeconds(totalSeconds)
Dim stringBuilder As StringBuilder = New StringBuilder()
Dim hours As Integer = timeSpan.Hours
Dim minutes As Integer = timeSpan.Minutes
Dim seconds As Integer = timeSpan.Seconds
stringBuilder.Append(ToText(hours, "hour"))
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(minutes, "minute"))
If minutes > 0 AndAlso seconds > 0 Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(seconds, "second"))
Return stringBuilder.ToString()
End Function
Private Function ToText(value As Integer, singularName As String) As String
If value = 0 Then Return String.Empty
If value = 1 Then Return String.Format("{0} {1}", value, singularName)
Return String.Format("{0} {1}s", value, singularName)
End Function
$endgroup$
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
1
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
1
$begingroup$
Then you need to query theTotalHoursproperty
$endgroup$
– Heslacher
9 hours ago
$begingroup$
Thank you. I had to changeDim stringBuilder As StringBuilder = New StringBuilder()toDim stringBuilder As New System.Text.StringBuilder()to make it work in SSRS.
$endgroup$
– BishNaboB
9 hours ago
|
show 1 more comment
$begingroup$
As @Hesclacher has given a fantastic answer, which is not only one that I have upvoted but I would personally mark it as the correct answer if I had the power, I am hesitant to improve upon it. But I would like to offer constructive feedback on your original code.
I have a personal distinction between being a VB Coder and a .NET Developer. I think you can use VB.NET and be what I define to be a .NET Developer - that is you are making traditional .NET calls like any C# dev would use. I define a VB Coder has someone who still thinks and codes with VBA in mind, and such a person relies upon some of the compatibility calls, such as CStr.
According to my own such definitions, a VB Coder would use CStr whereas a .NET Developer would use String.Format (as did Heschalcher) or better yet, Interpolated Strings.
VB Coder:
hourString = Cstr(hours) & " hours"
.NET Developer:
hourString = String.Format("{0} hours", hours)
Or
hourString = $"{hours} hours"
To calculate the number of hours, if you aren't going to use something nice like TimeSpan, I would change this line of code:
hours = floor(TotalSeconds / 3600)
To simply use integer division:
hours = TotalSeconds 3600
Also, VB.NET does support short-circuited conditionals (unlike VBA), so this line of code:
If hours > 0 and (minutes > 0 or seconds > 0) Then
could be changed to:
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
This example employs short-circuiting with the AndAlso and OrElse operators.
Again, Heschachler's answer with TimeSpan and StringBuilder is spot-on.
$endgroup$
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose thecstr()comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.
$endgroup$
– BishNaboB
4 hours ago
add a comment |
$begingroup$
Building on @RickDavin.
VB.Net also has a robust If() function that shortcuts the checks (unlike VBA's IIf() function)
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
Becomes
hourstring = If(hours = 1, "hour", "hours")
@Heslacher's function can then be:
Private Function ToText(value As Integer, singularName As String) As String
Return If(value = 0, String.Empty, String.Format("{0} {1}{2}", value, singularName, If(value=1,"","s")))
End Function
Note, I am still in the VB coder camp, and my kludge to the string builder format above is based some limited practice.
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
BishNaboB is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f223421%2fconvert-integer-to-full-text-string-duration%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
You should look into the TimeSpan struct, which provides a nice method TimeSpan.FromSeconds().
Having filled a TimeSpan struct by e.g calling the FromSeconds() method, you can just access its properties Seconds, Minutes and Hours.
Instead of concating strings like you do, you should consider to use a StringBuilder.
To get rid of the If ... Else If you can just use the singular and only if the value is greater than 1 you add a s to the string/StringBuilder.
Based on the .NET Naming Guidelines method parameters should be named using camelCase casing hence TotalSeconds should be totalSeconds
Implementing the mentioned points will look like so
Public Function SecondsFullText(ByVal totalSeconds As Double) As String
Dim timeSpan As TimeSpan = TimeSpan.FromSeconds(totalSeconds)
Dim stringBuilder As StringBuilder = New StringBuilder()
Dim hours As Integer = timeSpan.Hours
Dim minutes As Integer = timeSpan.Minutes
Dim seconds As Integer = timeSpan.Seconds
stringBuilder.Append(ToText(hours, "hour"))
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(minutes, "minute"))
If minutes > 0 AndAlso seconds > 0 Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(seconds, "second"))
Return stringBuilder.ToString()
End Function
Private Function ToText(value As Integer, singularName As String) As String
If value = 0 Then Return String.Empty
If value = 1 Then Return String.Format("{0} {1}", value, singularName)
Return String.Format("{0} {1}s", value, singularName)
End Function
$endgroup$
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
1
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
1
$begingroup$
Then you need to query theTotalHoursproperty
$endgroup$
– Heslacher
9 hours ago
$begingroup$
Thank you. I had to changeDim stringBuilder As StringBuilder = New StringBuilder()toDim stringBuilder As New System.Text.StringBuilder()to make it work in SSRS.
$endgroup$
– BishNaboB
9 hours ago
|
show 1 more comment
$begingroup$
You should look into the TimeSpan struct, which provides a nice method TimeSpan.FromSeconds().
Having filled a TimeSpan struct by e.g calling the FromSeconds() method, you can just access its properties Seconds, Minutes and Hours.
Instead of concating strings like you do, you should consider to use a StringBuilder.
To get rid of the If ... Else If you can just use the singular and only if the value is greater than 1 you add a s to the string/StringBuilder.
Based on the .NET Naming Guidelines method parameters should be named using camelCase casing hence TotalSeconds should be totalSeconds
Implementing the mentioned points will look like so
Public Function SecondsFullText(ByVal totalSeconds As Double) As String
Dim timeSpan As TimeSpan = TimeSpan.FromSeconds(totalSeconds)
Dim stringBuilder As StringBuilder = New StringBuilder()
Dim hours As Integer = timeSpan.Hours
Dim minutes As Integer = timeSpan.Minutes
Dim seconds As Integer = timeSpan.Seconds
stringBuilder.Append(ToText(hours, "hour"))
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(minutes, "minute"))
If minutes > 0 AndAlso seconds > 0 Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(seconds, "second"))
Return stringBuilder.ToString()
End Function
Private Function ToText(value As Integer, singularName As String) As String
If value = 0 Then Return String.Empty
If value = 1 Then Return String.Format("{0} {1}", value, singularName)
Return String.Format("{0} {1}s", value, singularName)
End Function
$endgroup$
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
1
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
1
$begingroup$
Then you need to query theTotalHoursproperty
$endgroup$
– Heslacher
9 hours ago
$begingroup$
Thank you. I had to changeDim stringBuilder As StringBuilder = New StringBuilder()toDim stringBuilder As New System.Text.StringBuilder()to make it work in SSRS.
$endgroup$
– BishNaboB
9 hours ago
|
show 1 more comment
$begingroup$
You should look into the TimeSpan struct, which provides a nice method TimeSpan.FromSeconds().
Having filled a TimeSpan struct by e.g calling the FromSeconds() method, you can just access its properties Seconds, Minutes and Hours.
Instead of concating strings like you do, you should consider to use a StringBuilder.
To get rid of the If ... Else If you can just use the singular and only if the value is greater than 1 you add a s to the string/StringBuilder.
Based on the .NET Naming Guidelines method parameters should be named using camelCase casing hence TotalSeconds should be totalSeconds
Implementing the mentioned points will look like so
Public Function SecondsFullText(ByVal totalSeconds As Double) As String
Dim timeSpan As TimeSpan = TimeSpan.FromSeconds(totalSeconds)
Dim stringBuilder As StringBuilder = New StringBuilder()
Dim hours As Integer = timeSpan.Hours
Dim minutes As Integer = timeSpan.Minutes
Dim seconds As Integer = timeSpan.Seconds
stringBuilder.Append(ToText(hours, "hour"))
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(minutes, "minute"))
If minutes > 0 AndAlso seconds > 0 Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(seconds, "second"))
Return stringBuilder.ToString()
End Function
Private Function ToText(value As Integer, singularName As String) As String
If value = 0 Then Return String.Empty
If value = 1 Then Return String.Format("{0} {1}", value, singularName)
Return String.Format("{0} {1}s", value, singularName)
End Function
$endgroup$
You should look into the TimeSpan struct, which provides a nice method TimeSpan.FromSeconds().
Having filled a TimeSpan struct by e.g calling the FromSeconds() method, you can just access its properties Seconds, Minutes and Hours.
Instead of concating strings like you do, you should consider to use a StringBuilder.
To get rid of the If ... Else If you can just use the singular and only if the value is greater than 1 you add a s to the string/StringBuilder.
Based on the .NET Naming Guidelines method parameters should be named using camelCase casing hence TotalSeconds should be totalSeconds
Implementing the mentioned points will look like so
Public Function SecondsFullText(ByVal totalSeconds As Double) As String
Dim timeSpan As TimeSpan = TimeSpan.FromSeconds(totalSeconds)
Dim stringBuilder As StringBuilder = New StringBuilder()
Dim hours As Integer = timeSpan.Hours
Dim minutes As Integer = timeSpan.Minutes
Dim seconds As Integer = timeSpan.Seconds
stringBuilder.Append(ToText(hours, "hour"))
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(minutes, "minute"))
If minutes > 0 AndAlso seconds > 0 Then
stringBuilder.Append(" ")
End If
stringBuilder.Append(ToText(seconds, "second"))
Return stringBuilder.ToString()
End Function
Private Function ToText(value As Integer, singularName As String) As String
If value = 0 Then Return String.Empty
If value = 1 Then Return String.Format("{0} {1}", value, singularName)
Return String.Format("{0} {1}s", value, singularName)
End Function
answered 10 hours ago
HeslacherHeslacher
45.5k4 gold badges67 silver badges162 bronze badges
45.5k4 gold badges67 silver badges162 bronze badges
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
1
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
1
$begingroup$
Then you need to query theTotalHoursproperty
$endgroup$
– Heslacher
9 hours ago
$begingroup$
Thank you. I had to changeDim stringBuilder As StringBuilder = New StringBuilder()toDim stringBuilder As New System.Text.StringBuilder()to make it work in SSRS.
$endgroup$
– BishNaboB
9 hours ago
|
show 1 more comment
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
1
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
1
$begingroup$
Then you need to query theTotalHoursproperty
$endgroup$
– Heslacher
9 hours ago
$begingroup$
Thank you. I had to changeDim stringBuilder As StringBuilder = New StringBuilder()toDim stringBuilder As New System.Text.StringBuilder()to make it work in SSRS.
$endgroup$
– BishNaboB
9 hours ago
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
Thank you for this. Unfortunately it doesn't look as though StringBuilder is valid in the VB implementation in SSRS/Report Builder 3.0. It returns this error: There is an error on line 46 of custom code: [BC30002] Type 'StringBuilder' is not defined.
$endgroup$
– BishNaboB
10 hours ago
1
1
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
You need to add an import to System. Text
$endgroup$
– Heslacher
10 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
$begingroup$
How does this handle a duration greater than 24 hours?
$endgroup$
– BishNaboB
9 hours ago
1
1
$begingroup$
Then you need to query the
TotalHours property$endgroup$
– Heslacher
9 hours ago
$begingroup$
Then you need to query the
TotalHours property$endgroup$
– Heslacher
9 hours ago
$begingroup$
Thank you. I had to change
Dim stringBuilder As StringBuilder = New StringBuilder() to Dim stringBuilder As New System.Text.StringBuilder() to make it work in SSRS.$endgroup$
– BishNaboB
9 hours ago
$begingroup$
Thank you. I had to change
Dim stringBuilder As StringBuilder = New StringBuilder() to Dim stringBuilder As New System.Text.StringBuilder() to make it work in SSRS.$endgroup$
– BishNaboB
9 hours ago
|
show 1 more comment
$begingroup$
As @Hesclacher has given a fantastic answer, which is not only one that I have upvoted but I would personally mark it as the correct answer if I had the power, I am hesitant to improve upon it. But I would like to offer constructive feedback on your original code.
I have a personal distinction between being a VB Coder and a .NET Developer. I think you can use VB.NET and be what I define to be a .NET Developer - that is you are making traditional .NET calls like any C# dev would use. I define a VB Coder has someone who still thinks and codes with VBA in mind, and such a person relies upon some of the compatibility calls, such as CStr.
According to my own such definitions, a VB Coder would use CStr whereas a .NET Developer would use String.Format (as did Heschalcher) or better yet, Interpolated Strings.
VB Coder:
hourString = Cstr(hours) & " hours"
.NET Developer:
hourString = String.Format("{0} hours", hours)
Or
hourString = $"{hours} hours"
To calculate the number of hours, if you aren't going to use something nice like TimeSpan, I would change this line of code:
hours = floor(TotalSeconds / 3600)
To simply use integer division:
hours = TotalSeconds 3600
Also, VB.NET does support short-circuited conditionals (unlike VBA), so this line of code:
If hours > 0 and (minutes > 0 or seconds > 0) Then
could be changed to:
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
This example employs short-circuiting with the AndAlso and OrElse operators.
Again, Heschachler's answer with TimeSpan and StringBuilder is spot-on.
$endgroup$
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose thecstr()comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.
$endgroup$
– BishNaboB
4 hours ago
add a comment |
$begingroup$
As @Hesclacher has given a fantastic answer, which is not only one that I have upvoted but I would personally mark it as the correct answer if I had the power, I am hesitant to improve upon it. But I would like to offer constructive feedback on your original code.
I have a personal distinction between being a VB Coder and a .NET Developer. I think you can use VB.NET and be what I define to be a .NET Developer - that is you are making traditional .NET calls like any C# dev would use. I define a VB Coder has someone who still thinks and codes with VBA in mind, and such a person relies upon some of the compatibility calls, such as CStr.
According to my own such definitions, a VB Coder would use CStr whereas a .NET Developer would use String.Format (as did Heschalcher) or better yet, Interpolated Strings.
VB Coder:
hourString = Cstr(hours) & " hours"
.NET Developer:
hourString = String.Format("{0} hours", hours)
Or
hourString = $"{hours} hours"
To calculate the number of hours, if you aren't going to use something nice like TimeSpan, I would change this line of code:
hours = floor(TotalSeconds / 3600)
To simply use integer division:
hours = TotalSeconds 3600
Also, VB.NET does support short-circuited conditionals (unlike VBA), so this line of code:
If hours > 0 and (minutes > 0 or seconds > 0) Then
could be changed to:
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
This example employs short-circuiting with the AndAlso and OrElse operators.
Again, Heschachler's answer with TimeSpan and StringBuilder is spot-on.
$endgroup$
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose thecstr()comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.
$endgroup$
– BishNaboB
4 hours ago
add a comment |
$begingroup$
As @Hesclacher has given a fantastic answer, which is not only one that I have upvoted but I would personally mark it as the correct answer if I had the power, I am hesitant to improve upon it. But I would like to offer constructive feedback on your original code.
I have a personal distinction between being a VB Coder and a .NET Developer. I think you can use VB.NET and be what I define to be a .NET Developer - that is you are making traditional .NET calls like any C# dev would use. I define a VB Coder has someone who still thinks and codes with VBA in mind, and such a person relies upon some of the compatibility calls, such as CStr.
According to my own such definitions, a VB Coder would use CStr whereas a .NET Developer would use String.Format (as did Heschalcher) or better yet, Interpolated Strings.
VB Coder:
hourString = Cstr(hours) & " hours"
.NET Developer:
hourString = String.Format("{0} hours", hours)
Or
hourString = $"{hours} hours"
To calculate the number of hours, if you aren't going to use something nice like TimeSpan, I would change this line of code:
hours = floor(TotalSeconds / 3600)
To simply use integer division:
hours = TotalSeconds 3600
Also, VB.NET does support short-circuited conditionals (unlike VBA), so this line of code:
If hours > 0 and (minutes > 0 or seconds > 0) Then
could be changed to:
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
This example employs short-circuiting with the AndAlso and OrElse operators.
Again, Heschachler's answer with TimeSpan and StringBuilder is spot-on.
$endgroup$
As @Hesclacher has given a fantastic answer, which is not only one that I have upvoted but I would personally mark it as the correct answer if I had the power, I am hesitant to improve upon it. But I would like to offer constructive feedback on your original code.
I have a personal distinction between being a VB Coder and a .NET Developer. I think you can use VB.NET and be what I define to be a .NET Developer - that is you are making traditional .NET calls like any C# dev would use. I define a VB Coder has someone who still thinks and codes with VBA in mind, and such a person relies upon some of the compatibility calls, such as CStr.
According to my own such definitions, a VB Coder would use CStr whereas a .NET Developer would use String.Format (as did Heschalcher) or better yet, Interpolated Strings.
VB Coder:
hourString = Cstr(hours) & " hours"
.NET Developer:
hourString = String.Format("{0} hours", hours)
Or
hourString = $"{hours} hours"
To calculate the number of hours, if you aren't going to use something nice like TimeSpan, I would change this line of code:
hours = floor(TotalSeconds / 3600)
To simply use integer division:
hours = TotalSeconds 3600
Also, VB.NET does support short-circuited conditionals (unlike VBA), so this line of code:
If hours > 0 and (minutes > 0 or seconds > 0) Then
could be changed to:
If hours > 0 AndAlso (minutes > 0 OrElse seconds > 0) Then
This example employs short-circuiting with the AndAlso and OrElse operators.
Again, Heschachler's answer with TimeSpan and StringBuilder is spot-on.
answered 6 hours ago
Rick DavinRick Davin
3,3528 silver badges19 bronze badges
3,3528 silver badges19 bronze badges
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose thecstr()comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.
$endgroup$
– BishNaboB
4 hours ago
add a comment |
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose thecstr()comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.
$endgroup$
– BishNaboB
4 hours ago
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose the
cstr() comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.$endgroup$
– BishNaboB
4 hours ago
$begingroup$
Hi Rick. Thank you for the distinction between coder types, it's an interesting observation. I suppose the
cstr() comes from the fact this is code added to a report in SSRS, which uses those functions. Short circuiting is something I use in SSRS, and forgot to add in to the code example. Integer division is not something I'm overly familiar with so gives me something to read up on.$endgroup$
– BishNaboB
4 hours ago
add a comment |
$begingroup$
Building on @RickDavin.
VB.Net also has a robust If() function that shortcuts the checks (unlike VBA's IIf() function)
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
Becomes
hourstring = If(hours = 1, "hour", "hours")
@Heslacher's function can then be:
Private Function ToText(value As Integer, singularName As String) As String
Return If(value = 0, String.Empty, String.Format("{0} {1}{2}", value, singularName, If(value=1,"","s")))
End Function
Note, I am still in the VB coder camp, and my kludge to the string builder format above is based some limited practice.
$endgroup$
add a comment |
$begingroup$
Building on @RickDavin.
VB.Net also has a robust If() function that shortcuts the checks (unlike VBA's IIf() function)
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
Becomes
hourstring = If(hours = 1, "hour", "hours")
@Heslacher's function can then be:
Private Function ToText(value As Integer, singularName As String) As String
Return If(value = 0, String.Empty, String.Format("{0} {1}{2}", value, singularName, If(value=1,"","s")))
End Function
Note, I am still in the VB coder camp, and my kludge to the string builder format above is based some limited practice.
$endgroup$
add a comment |
$begingroup$
Building on @RickDavin.
VB.Net also has a robust If() function that shortcuts the checks (unlike VBA's IIf() function)
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
Becomes
hourstring = If(hours = 1, "hour", "hours")
@Heslacher's function can then be:
Private Function ToText(value As Integer, singularName As String) As String
Return If(value = 0, String.Empty, String.Format("{0} {1}{2}", value, singularName, If(value=1,"","s")))
End Function
Note, I am still in the VB coder camp, and my kludge to the string builder format above is based some limited practice.
$endgroup$
Building on @RickDavin.
VB.Net also has a robust If() function that shortcuts the checks (unlike VBA's IIf() function)
If hours = 1 Then
hourString = Cstr(hours) & " hour"
Else If hours > 1 Then
hourString = Cstr(hours) & " hours"
End If
Becomes
hourstring = If(hours = 1, "hour", "hours")
@Heslacher's function can then be:
Private Function ToText(value As Integer, singularName As String) As String
Return If(value = 0, String.Empty, String.Format("{0} {1}{2}", value, singularName, If(value=1,"","s")))
End Function
Note, I am still in the VB coder camp, and my kludge to the string builder format above is based some limited practice.
answered 2 hours ago
AJDAJD
1,5871 gold badge3 silver badges13 bronze badges
1,5871 gold badge3 silver badges13 bronze badges
add a comment |
add a comment |
BishNaboB is a new contributor. Be nice, and check out our Code of Conduct.
BishNaboB is a new contributor. Be nice, and check out our Code of Conduct.
BishNaboB is a new contributor. Be nice, and check out our Code of Conduct.
BishNaboB is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f223421%2fconvert-integer-to-full-text-string-duration%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
It would be easier to provide a review and answer if the function that called this or displayed the resulting string was included as well.
$endgroup$
– pacmaninbw
10 hours ago
$begingroup$
@pacmaninbw Noted, and updated. There's no real function that calls it as it's for use in a report in SSRS.
$endgroup$
– BishNaboB
10 hours ago
$begingroup$
I did this as a one-liner in groovy for fun--converted milliseconds to something like 1d2h3m10s. I don't think I have the one-liner any more but I converted it into 4 significantly more readable lines you're welcome to if you want them :) (Now it's part of Java so I don't really need it any more, you can have it)
$endgroup$
– Bill K
2 hours ago
$begingroup$
Code aside, "an integer" has no units and cannot be converted to a string representation of time with additionally specifying units. So you don't just have an integer; you have an integer number of seconds. You need to be more careful about this in your documentation and communication.
$endgroup$
– jpmc26
2 hours ago