Formatting a negative TimeSpan
Asked Answered
I

7

33

I'm doing some math with the Timespans in .Net, and occasionally the sum results in a negative Timespan. When I display the result I am having trouble formatting it to include the negative indicator.

Dim ts as New Timespan(-10,0,0)

ts.ToString()

This will display "-10:00:00", which is good but I don't want to show the seconds so tried this.

ts.ToString("hh\:mm")

This returns "10:00" and has dropped the "-" from the front which is the crux of the issue. My current solution is this:

If(ts < TimeSpan.Zero, "-", "") & ts.ToString("hh\:mm")

but I was hoping to accomplish the same by using only the format string.

Impostume answered 11/7, 2010 at 17:2 Comment(1)
So very strange. MSDN suggests this is supported, via the 'c' format, but if you use it in a custom format, it crashes msdn.microsoft.com/en-us/library/ee372286(v=vs.100).aspxLatent
C
16

I've used .Net Reflector on TimeSpan.ToString(...) and it really doesn't look like it supports any form of negative prefix on custom formats - so I think you're out of luck when it comes to getting it to work for you as above. :(

Chambliss answered 11/7, 2010 at 17:33 Comment(0)
Q
10

It seems like you're stuck with that code, but if so, this seems like a great time to write an extesion method, that way you can make your code clearer and you don't have to repeat that code in multiple places, so something like:

Module Extensions
    <System.Runtime.CompilerServices.Extension()> _
    Public Function HoursAndMinutes(ByVal ts As TimeSpan) As String
        Return If(ts < TimeSpan.Zero, "-", "") & ts.ToString("hh\:mm")
    End Function
End Module

And then you could just call it as:

ts.HoursAndMinutes()
Quieten answered 11/7, 2010 at 18:2 Comment(3)
This could be considered an abuse of extension methods with a format that specific.Antiphony
@mattmc3: Well I probably wouldn't write one like these and put in a generic library, but to make a specific project to be more readable I wouldn't worry about that.Quieten
I did end up implementing this as an extension method, so thanks. Gave the answer to Will as he was the first to confirm it could not be done with the format string alone. Possibly abuse matt, but nearly every textbox in this app needs to be formatted this way so I think its ok in this case.Impostume
A
2

I agree with Will. MSDN and Reflector both indicate that you're out of luck. The best you're gonna get is to either use what you have, write your own IFormatProvider, or use one of the standard formats for timespan like "g".

Antiphony answered 11/7, 2010 at 17:45 Comment(0)
P
2

I'm using this fugly code:

if (timeDiff.TotalSeconds < 0)
           {
               timeDiff = timeDiff.Negate();
               TimeChangeTb.Text = string.Format("-{0:D2}:{1:D2}:{2:D2}",
               timeDiff.Hours,
               timeDiff.Minutes,
               timeDiff.Seconds);
           }
           else
           {
               TimeChangeTb.Text = string.Format("{0:D2}:{1:D2}:{2:D2}",
               timeDiff.Hours,
               timeDiff.Minutes,
               timeDiff.Seconds);
           }

Hope it helps!

Prolepsis answered 24/9, 2013 at 13:28 Comment(0)
S
1

The standard format "c" provides the negative sign, but includes all parts of the timespan.

    Dim ts As New TimeSpan(-10, 1, 2)
    Debug.WriteLine(ts.ToString("c"))
Surplice answered 12/7, 2010 at 11:29 Comment(0)
P
0

Based on @ho1 answer, I've built an extension method. Might be a little easier to use nowadays.

public static class TimeSpanUtil
{
    public static string HoursAndMinutes(this TimeSpan ts) 
    {
        return (ts < TimeSpan.Zero ? "-" : "") + ts.ToString("hh:mm");     
    }        
}
Piperonal answered 15/7, 2014 at 8:12 Comment(0)
M
0

After testing different approaches, here is what I did:

Public Module TimeExtensions
    <Extension>
    Public Function ToHourMinute(ByVal time As TimeSpan) As String
        Return $"{If(time < TimeSpan.Zero, "-", "")}{time:hh\:mm}"
    End Function
End Module
Monogamist answered 3/12, 2020 at 18:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.