Respuestas:
Tenga en cuenta: esta respuesta es para .Net 4.0 y superior. Si desea formatear un TimeSpan en .Net 3.5 o inferior, consulte la respuesta de JohannesH .
Se introdujeron cadenas de formato TimeSpan personalizadas en .Net 4.0. Puede encontrar una referencia completa de los especificadores de formato disponibles en la página de cadenas de formato de TimeSpan personalizado de MSDN .
Aquí hay una cadena de formato de intervalo de tiempo de ejemplo:
string.Format("{0:hh\\:mm\\:ss}", myTimeSpan); //example output 15:36:15
( ACTUALIZACIÓN ) y aquí hay un ejemplo usando la interpolación de cadenas C # 6:
$"{myTimeSpan:hh\\:mm\\:ss}"; //example output 15:36:15
Debe escapar del carácter ":" con un "\" (que se debe escapar a menos que esté utilizando una cadena literal).
Este extracto de la página de cadenas de formato de TimeSpan personalizado de MSDN explica cómo escapar de ":" y "." caracteres en una cadena de formato:
Los especificadores de formato de TimeSpan personalizados no incluyen símbolos de separador de marcador de posición, como los símbolos que separan días de horas, horas de minutos o segundos de segundos fraccionarios. En cambio, estos símbolos deben incluirse en la cadena de formato personalizado como literales de cadena. Por ejemplo, "dd.hh: mm" define un punto (.) Como el separador entre días y horas, y dos puntos (:) como el separador entre horas y minutos.
myTimeSpan = new TimeSpan(15, 35, 54);
la declaración myTimeSpan .ToString("hh\\mm\\ss");
dará como resultado 15m35s54
. No creo que sea lo que pretendías, ya que colocará una m después de tus horas y una s después de tus minutos.
$"{myTimeSpan.TotalHours}:{myTimeSpan:mm\\:ss}"
. Desde el punto de vista del usuario, podría ser mejor mostrar los días, sin embargo, nadie quiere calcular mentalmente cuántos días hay en más de 200 horas.
Para .NET 3.5 y versiones anteriores, puede usar:
string.Format ("{0:00}:{1:00}:{2:00}",
(int)myTimeSpan.TotalHours,
myTimeSpan.Minutes,
myTimeSpan.Seconds);
Código tomado de una respuesta de Jon Skeet en bytes
Para .NET 4.0 y superior, vea DoctaJonez respuesta de .
Una forma es crear un DateTime
objeto y usarlo para formatear:
new DateTime(myTimeSpan.Ticks).ToString(myCustomFormat)
// or using String.Format:
String.Format("{0:HHmmss}", new DateTime(myTimeSpan.Ticks))
Así es como lo sé. Espero que alguien pueda sugerir una mejor manera.
Sencillo. Usar TimeSpan.ToString
con c, go G. Más información en MSDN
Yo iria con
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"))
Funciona para Framework 4
Personalmente, me gusta este enfoque:
TimeSpan ts = ...;
string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", ts);
Puedes hacer esto tan personalizado como quieras sin problemas:
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);
También puedes ir con:
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")
EDITAR:
También puedes mirar 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");
Todos los caracteres literales deben escapar.
Usé el código a continuación. Es largo, pero aún así es una expresión, y produce una salida muy amigable, ya que no genera días, horas, minutos o segundos si tienen un valor de cero.
En la muestra produce resultados: "4 días 1 hora 3 segundos".
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" : ""); }
Llame a eso para cada componente (por ejemplo timeComponent(sp.Days, "day")
), luego use String.join
para insertar los espacios.
Yo uso este metodo Soy belga y hablo holandés, así que plural de horas y minutos no es solo agregar 's' al final, sino casi una palabra diferente de singular.
Puede parecer largo, pero creo que es muy legible:
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
Este es el enfoque que utilicé con formato condicional. y lo publico aquí porque creo que es una forma limpia.
$"{time.Days:#0:;;\\}{time.Hours:#0:;;\\}{time.Minutes:00:}{time.Seconds:00}"
ejemplo de salidas:
00:00
(mínimo)
1:43:04
(cuando tenemos horas)
15:03:01
(cuando las horas son más de 1 dígito)
2:4:22:04
(cuando tenemos días)
El formateo es fácil. time.Days:#0:;;\\
El formato anterior ;;
es para cuando el valor es positivo. Los valores negativos se ignoran. y para valores cero tenemos ;;\\
para ocultarlo en una cadena con formato. tenga en cuenta que la barra invertida escapada es necesaria; de lo contrario, no se formateará correctamente.
Aquí está mi método de extensión :
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));
}
Llamada de ejemplo:
string time = new TimeSpan(3, 14, 15, 0, 65).ToFormattedString();
Salida:
3 days, 14 hours, 15 minutes, 65 milliseconds
Esto es una molestia en VS 2010, aquí está mi solución alternativa.
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;
}
}
}
El Substring
método funciona perfectamente cuando solo quieres las Horas: Minutos: Segundos. Es un código simple, limpio y fácil de entender.
var yourTimeSpan = DateTime.Now - DateTime.Now.AddMinutes(-2);
var formatted = yourTimeSpan.ToString().Substring(0,8);// 00:00:00
Console.WriteLine(formatted);
Aquí está mi versión. Muestra solo lo necesario, maneja la pluralización, los negativos, y traté de hacerlo liviano.
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;
}
}
Si desea un formato de duración similar al de YouTube, dada la cantidad de segundos
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));
}
Salida:
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
Quería devolver una cadena como "1 día 2 horas 3 minutos" y también tener en cuenta si, por ejemplo, los días o los minutos son 0 y luego no se muestran. gracias a John Rasch por su respuesta, que la mía es apenas una extensión de
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 ");