How to format the HH:mm:ss separators of a TimeSpa

2019-02-12 23:47发布

问题:

I'm working on an app that may be seen in many countries in the world. There are not many countries that show hours, minutes and seconds with something other than : as a seperator but there are a few and I want to make sure that times are formatted correctly for their region. DateTime is great at this but TimeSpan isn't. These snippets are from my immediate Window in Visual Studio 2010 using .Net 4 with my region set to Malayalam (India). The dateTime.Now call also reflects how time is shown on my clock, Microsoft Outlook and other areas.

DateTime.Now.ToString()
"02-10-12 17.00.58"

http://msdn.microsoft.com/en-us/library/dd784379.aspx Says "If formatProvider is null, the DateTimeFormatInfo object that is associated with the current culture is used. If format is a custom format string, the formatProvider parameter is ignored." It stands to reason then that i shouldn't need to even pass in the Current CultureInfo. The format i want here is hh.mm.ss but obvioulsy hh:mm:ss when in most other languages, and if there are anoy other poossibilities, it should automatically reflect those too - basically TimeSpan should be culture-Aware, just as DateTime is.

However:

timeRemaining.ToString()
"00:02:09"
timeRemaining.ToString("c")
"00:02:09"
timeRemaining.ToString("c", CultureInfo.CurrentCulture)
"00:02:09"
timeRemaining.ToString("g")
"0:02:09"
timeRemaining.ToString("G")
"0:00:02:09.0000000"
timeRemaining.ToString("t")
"00:02:09"
timeRemaining.ToString("g", CultureInfo.CurrentCulture)
"0:02:09"
timeRemaining.ToString("g", CultureInfo.CurrentUICulture)
"0:02:09"
timeRemaining.ToString("G", CultureInfo.CurrentUICulture)
"0:00:02:09.0000000"
timeRemaining.ToString("G", CultureInfo.CurrentCulture)
"0:00:02:09.0000000"
timeRemaining.ToString("t", CultureInfo.CurrentCulture)
"00:02:09"

I'm looking for a simple, single line to output a timeSpan in a culture-Aware manner. Any ideas are appreciated.

回答1:

Looks like a bug, you can report it at connect.microsoft.com. Meanwhile, a workaround is to take advantage of DateTime formatting. Like this:

using System;
using System.Globalization;

class Program {
    static void Main(string[] args) {
        var ci = CultureInfo.GetCultureInfo("ml-IN");
        System.Threading.Thread.CurrentThread.CurrentCulture = ci;
        var ts = new TimeSpan(0, 2, 9);
        var dt = new DateTime(Math.Abs(ts.Ticks));
        Console.WriteLine(dt.ToString("HH:mm:ss"));
        Console.ReadLine();
    }
}

Output:

00.02.09



回答2:

This is more like a comment, but needs some space, so I write it as an answer.

While string formatting of DateTime has been in .NET for a very long time, formatting of TimeSpan was new in .NET 4.0 (Visual Studio 2010).

A culture has a DateTimeFormatInfo object which is used by DateTime and includes info on whether to use colon : or period . or something else between hours, minutes and seconds. Now, TimeSpan does not seem to use this DateTimeFormatInfo object, and there is nothing called "TimeSpanFormatInfo".

Here's an example:

// we start from a non-read-only invariant culture
Thread.CurrentThread.CurrentCulture = new CultureInfo("");

// change time separator of DateTime format info of the culture
CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator = "<-->";

var dt = new DateTime(2013, 7, 8, 13, 14, 15);
Console.WriteLine(dt);  // writes "07/08/2013 13<-->14<-->15"

var ts = new TimeSpan(13, 14, 15);
Console.WriteLine(ts);  // writes "13:14:15"


回答3:

I'm looking for a simple, single line to output a timeSpan in a culture-Aware manner.

Then I think you're best off using the DateTime class to do the formatting for you:

string display = new DateTime(timespan.Ticks).ToLongTimeString();

Assuming that timespan holds a positive duration between 0 and 24 hours long.