Odpowiedzi:
Uwaga: ta odpowiedź dotyczy wersji .Net 4.0 i nowszych. Jeśli chcesz sformatować TimeSpan w .Net 3.5 lub niższej, zapoznaj się z odpowiedzią JohannesH .
Niestandardowe ciągi formatu TimeSpan zostały wprowadzone w .Net 4.0. Pełne odniesienie do dostępnych specyfikatorów formatu można znaleźć na stronie Ciągi formatu niestandardowego formatu czasu MSDN .
Oto przykładowy ciąg formatu okresu:
string.Format("{0:hh\\:mm\\:ss}", myTimeSpan); //example output 15:36:15
( UPDATE ), a oto przykład z interpolacją ciągów C # 6:
$"{myTimeSpan:hh\\:mm\\:ss}"; //example output 15:36:15
Musisz uciec ze znaku „:” za pomocą „\” (który sam musi być poprzedzony znakiem ucieczki, chyba że używasz pełnego ciągu).
Ten fragment strony MSDN Niestandardowe ciągi formatu formatu TimeSpan wyjaśnia, jak unikać znaków „:” i „.” znaki w ciągu formatu:
Specyfikatory niestandardowego formatu TimeSpan nie zawierają symboli zastępczych symboli zastępczych, takich jak symbole, które oddzielają dni od godzin, godzin od minut lub sekund od ułamków sekund. Zamiast tego symbole te muszą być zawarte w ciągu formatu niestandardowego jako literały ciągu. Na przykład „dd.hh: mm” definiuje kropkę (.) Jako separator między dniami a godzinami, a dwukropek (:) jako separator między godzinami a minutami.
myTimeSpan = new TimeSpan(15, 35, 54);
instrukcji myTimeSpan .ToString("hh\\mm\\ss");
będzie wynik 15m35s54
. Nie sądzę, że to było to, co zamierzałeś, ponieważ będzie to m po twoich godzinach i s po twoich minutach.
$"{myTimeSpan.TotalHours}:{myTimeSpan:mm\\:ss}"
. Z punktu widzenia użytkownika może być lepiej podać liczbę dni, nikt nie chce mentalnie dowiedzieć się, ile dni zajmuje ponad 200 godzin.
W przypadku .NET 3.5 i niższych można użyć:
string.Format ("{0:00}:{1:00}:{2:00}",
(int)myTimeSpan.TotalHours,
myTimeSpan.Minutes,
myTimeSpan.Seconds);
Kod pochodzi z Jon Skeet odpowiedź na bajty
W przypadku platformy .NET 4.0 i nowszych patrz odpowiedź DoctaJonez .
Jednym ze sposobów jest utworzenie DateTime
obiektu i użycie go do formatowania:
new DateTime(myTimeSpan.Ticks).ToString(myCustomFormat)
// or using String.Format:
String.Format("{0:HHmmss}", new DateTime(myTimeSpan.Ticks))
W ten sposób wiem. Mam nadzieję, że ktoś może zaproponować lepszy sposób.
Prosty. Używaj TimeSpan.ToString
z c, g lub G. Więcej informacji na MSDN
Poszedłbym z
myTimeSpan.ToString("hh\\:mm\\:ss");
Dim duration As New TimeSpan(1, 12, 23, 62)
DEBUG.WriteLine("Time of Travel: " + duration.ToString("dd\.hh\:mm\:ss"))
Działa dla Framework 4
Osobiście podoba mi się to podejście:
TimeSpan ts = ...;
string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", ts);
Możesz to zrobić tak, jak chcesz, bez żadnych problemów:
string.Format("{0:%d}days {0:%h}hours {0:%m}min {0:%s}sec", ts);
string.Format("{0:%d}d {0:%h}h {0:%m}' {0:%s}''", ts);
Możesz także skorzystać z:
Dim ts As New TimeSpan(35, 21, 59, 59) '(11, 22, 30, 30) '
Dim TimeStr1 As String = String.Format("{0:c}", ts)
Dim TimeStr2 As String = New Date(ts.Ticks).ToString("dd.HH:mm:ss")
EDYTOWAĆ:
Możesz także spojrzeć na Strings.Format .
Dim ts As New TimeSpan(23, 30, 59)
Dim str As String = Strings.Format(New DateTime(ts.Ticks), "H:mm:ss")
if (timeSpan.TotalDays < 1)
return timeSpan.ToString(@"hh\:mm\:ss");
return timeSpan.TotalDays < 2
? timeSpan.ToString(@"d\ \d\a\y\ hh\:mm\:ss")
: timeSpan.ToString(@"d\ \d\a\y\s\ hh\:mm\:ss");
Wszystkie dosłowne znaki muszą zostać usunięte.
Użyłem kodu poniżej. Jest długi, ale nadal jest jednym wyrażeniem i daje bardzo przyjazny wynik, ponieważ nie generuje dni, godzin, minut ani sekund, jeśli mają wartość zero.
W próbce daje wynik: „4 dni 1 godzina 3 sekundy”.
TimeSpan sp = new TimeSpan(4,1,0,3);
string.Format("{0}{1}{2}{3}",
sp.Days > 0 ? ( sp.Days > 1 ? sp.ToString(@"d\ \d\a\y\s\ "): sp.ToString(@"d\ \d\a\y\ ")):string.Empty,
sp.Hours > 0 ? (sp.Hours > 1 ? sp.ToString(@"h\ \h\o\u\r\s\ ") : sp.ToString(@"h\ \h\o\u\r\ ")):string.Empty,
sp.Minutes > 0 ? (sp.Minutes > 1 ? sp.ToString(@"m\ \m\i\n\u\t\e\s\ ") :sp.ToString(@"m\ \m\i\n\u\t\e\ ")):string.Empty,
sp.Seconds > 0 ? (sp.Seconds > 1 ? sp.ToString(@"s\ \s\e\c\o\n\d\s"): sp.ToString(@"s\ \s\e\c\o\n\d\s")):string.Empty);
String timeComponent(int value, String name) { return value > 0 ? value + " " + name + (value > 1 ? "s" : ""); }
Nazwij to dla każdego komponentu (np. timeComponent(sp.Days, "day")
), A następnie użyj, String.join
aby wstawić spacje.
Używam tej metody. Jestem Belgiem i mówię po holendersku, więc liczba godzin i minut to nie tylko dodanie „s” na końcu, ale prawie inne słowo niż liczba pojedyncza.
To może wydawać się długie, ale myślę, że jest bardzo czytelne:
public static string SpanToReadableTime(TimeSpan span)
{
string[] values = new string[4]; //4 slots: days, hours, minutes, seconds
StringBuilder readableTime = new StringBuilder();
if (span.Days > 0)
{
if (span.Days == 1)
values[0] = span.Days.ToString() + " dag"; //day
else
values[0] = span.Days.ToString() + " dagen"; //days
readableTime.Append(values[0]);
readableTime.Append(", ");
}
else
values[0] = String.Empty;
if (span.Hours > 0)
{
if (span.Hours == 1)
values[1] = span.Hours.ToString() + " uur"; //hour
else
values[1] = span.Hours.ToString() + " uren"; //hours
readableTime.Append(values[1]);
readableTime.Append(", ");
}
else
values[1] = string.Empty;
if (span.Minutes > 0)
{
if (span.Minutes == 1)
values[2] = span.Minutes.ToString() + " minuut"; //minute
else
values[2] = span.Minutes.ToString() + " minuten"; //minutes
readableTime.Append(values[2]);
readableTime.Append(", ");
}
else
values[2] = string.Empty;
if (span.Seconds > 0)
{
if (span.Seconds == 1)
values[3] = span.Seconds.ToString() + " seconde"; //second
else
values[3] = span.Seconds.ToString() + " seconden"; //seconds
readableTime.Append(values[3]);
}
else
values[3] = string.Empty;
return readableTime.ToString();
}//end SpanToReadableTime
Takie podejście zastosowałem w przypadku formatowania warunkowego. i zamieszczam go tutaj, ponieważ uważam, że to czysty sposób.
$"{time.Days:#0:;;\\}{time.Hours:#0:;;\\}{time.Minutes:00:}{time.Seconds:00}"
przykład wyników:
00:00
(minimum)
1:43:04
(kiedy mamy godziny)
15:03:01
(gdy godziny są dłuższe niż 1 cyfra)
2:4:22:04
(kiedy mamy dni.)
Formatowanie jest łatwe. time.Days:#0:;;\\
poprzedni format ;;
dotyczy sytuacji, gdy wartość jest dodatnia. wartości ujemne są ignorowane. a dla wartości zerowych mamy ;;\\
, aby ukryć go w sformatowanym ciągu. zwróć uwagę, że odwrócony ukośnik jest konieczny, w przeciwnym razie nie zostanie poprawnie sformatowany.
Oto moja metoda rozszerzenia :
public static string ToFormattedString(this TimeSpan ts)
{
const string separator = ", ";
if (ts.TotalMilliseconds < 1) { return "No time"; }
return string.Join(separator, new string[]
{
ts.Days > 0 ? ts.Days + (ts.Days > 1 ? " days" : " day") : null,
ts.Hours > 0 ? ts.Hours + (ts.Hours > 1 ? " hours" : " hour") : null,
ts.Minutes > 0 ? ts.Minutes + (ts.Minutes > 1 ? " minutes" : " minute") : null,
ts.Seconds > 0 ? ts.Seconds + (ts.Seconds > 1 ? " seconds" : " second") : null,
ts.Milliseconds > 0 ? ts.Milliseconds + (ts.Milliseconds > 1 ? " milliseconds" : " millisecond") : null,
}.Where(t => t != null));
}
Przykładowe wywołanie:
string time = new TimeSpan(3, 14, 15, 0, 65).ToFormattedString();
Wynik:
3 days, 14 hours, 15 minutes, 65 milliseconds
To jest problem w VS 2010, oto moje rozwiązanie obejścia.
public string DurationString
{
get
{
if (this.Duration.TotalHours < 24)
return new DateTime(this.Duration.Ticks).ToString("HH:mm");
else //If duration is more than 24 hours
{
double totalminutes = this.Duration.TotalMinutes;
double hours = totalminutes / 60;
double minutes = this.Duration.TotalMinutes - (Math.Floor(hours) * 60);
string result = string.Format("{0}:{1}", Math.Floor(hours).ToString("00"), Math.Floor(minutes).ToString("00"));
return result;
}
}
}
Ta Substring
metoda działa idealnie, gdy chcesz tylko Godziny: Minuty: Sekundy. Jest to prosty, przejrzysty kod i łatwy do zrozumienia.
var yourTimeSpan = DateTime.Now - DateTime.Now.AddMinutes(-2);
var formatted = yourTimeSpan.ToString().Substring(0,8);// 00:00:00
Console.WriteLine(formatted);
Oto moja wersja. Pokazuje tylko tyle, ile jest to konieczne, radzi sobie z pluralizacją, negatywami i starałem się, aby była lekka.
0 seconds
1.404 seconds
1 hour, 14.4 seconds
14 hours, 57 minutes, 22.473 seconds
1 day, 14 hours, 57 minutes, 22.475 seconds
public static class TimeSpanExtensions
{
public static string ToReadableString(this TimeSpan timeSpan)
{
int days = (int)(timeSpan.Ticks / TimeSpan.TicksPerDay);
long subDayTicks = timeSpan.Ticks % TimeSpan.TicksPerDay;
bool isNegative = false;
if (timeSpan.Ticks < 0L)
{
isNegative = true;
days = -days;
subDayTicks = -subDayTicks;
}
int hours = (int)((subDayTicks / TimeSpan.TicksPerHour) % 24L);
int minutes = (int)((subDayTicks / TimeSpan.TicksPerMinute) % 60L);
int seconds = (int)((subDayTicks / TimeSpan.TicksPerSecond) % 60L);
int subSecondTicks = (int)(subDayTicks % TimeSpan.TicksPerSecond);
double fractionalSeconds = (double)subSecondTicks / TimeSpan.TicksPerSecond;
var parts = new List<string>(4);
if (days > 0)
parts.Add(string.Format("{0} day{1}", days, days == 1 ? null : "s"));
if (hours > 0)
parts.Add(string.Format("{0} hour{1}", hours, hours == 1 ? null : "s"));
if (minutes > 0)
parts.Add(string.Format("{0} minute{1}", minutes, minutes == 1 ? null : "s"));
if (fractionalSeconds.Equals(0D))
{
switch (seconds)
{
case 0:
// Only write "0 seconds" if we haven't written anything at all.
if (parts.Count == 0)
parts.Add("0 seconds");
break;
case 1:
parts.Add("1 second");
break;
default:
parts.Add(seconds + " seconds");
break;
}
}
else
{
parts.Add(string.Format("{0}{1:.###} seconds", seconds, fractionalSeconds));
}
string resultString = string.Join(", ", parts);
return isNegative ? "(negative) " + resultString : resultString;
}
}
Jeśli chcesz format czasu trwania podobny do youtube, biorąc pod uwagę liczbę sekund
int[] duration = { 0, 4, 40, 59, 60, 61, 400, 4000, 40000, 400000 };
foreach (int d in duration)
{
Console.WriteLine("{0, 6} -> {1, 10}", d, d > 59 ? TimeSpan.FromSeconds(d).ToString().TrimStart("00:".ToCharArray()) : string.Format("0:{0:00}", d));
}
Wynik:
0 -> 0:00
4 -> 0:04
40 -> 0:40
59 -> 0:59
60 -> 1:00
61 -> 1:01
400 -> 6:40
4000 -> 1:06:40
40000 -> 11:06:40
400000 -> 4.15:06:40
Chciałem zwrócić ciąg znaków, taki jak „1 dzień 2 godziny 3 minuty”, a także wziąć pod uwagę, jeśli na przykład dni lub minuty są równe 0, a następnie ich nie pokazuje. dzięki Johnowi Raschowi za odpowiedź, której moje jest zaledwie przedłużeniem
TimeSpan timeLeft = New Timespan(0, 70, 0);
String.Format("{0}{1}{2}{3}{4}{5}",
Math.Floor(timeLeft.TotalDays) == 0 ? "" :
Math.Floor(timeLeft.TotalDays).ToString() + " ",
Math.Floor(timeLeft.TotalDays) == 0 ? "" : Math.Floor(timeLeft.TotalDays) == 1 ? "day " : "days ",
timeLeft.Hours == 0 ? "" : timeLeft.Hours.ToString() + " ",
timeLeft.Hours == 0 ? "" : timeLeft.Hours == 1 ? "hour " : "hours ",
timeLeft.Minutes == 0 ? "" : timeLeft.Minutes.ToString() + " ",
timeLeft.Minutes == 0 ? "" : timeLeft.Minutes == 1 ? "minute " : "minutes ");