Réponses:
Remarque: cette réponse concerne .Net 4.0 et supérieur. Si vous souhaitez formater un TimeSpan en .Net 3.5 ou inférieur, veuillez consulter la réponse de JohannesH .
Les chaînes de format TimeSpan personnalisées ont été introduites dans .Net 4.0. Vous pouvez trouver une référence complète des spécificateurs de format disponibles sur la page MSDN Custom TimeSpan Format Strings .
Voici un exemple de chaîne de format de période:
string.Format("{0:hh\\:mm\\:ss}", myTimeSpan); //example output 15:36:15
( UPDATE ) et voici un exemple utilisant l'interpolation de chaîne C # 6:
$"{myTimeSpan:hh\\:mm\\:ss}"; //example output 15:36:15
Vous devez échapper le caractère ":" avec un "\" (qui lui-même doit être échappé sauf si vous utilisez une chaîne textuelle).
Cet extrait de la page MSDN Custom TimeSpan Format Strings explique comment échapper à ":" et "". caractères dans une chaîne de format:
Les spécificateurs de format TimeSpan personnalisés n'incluent pas de symboles de séparation d'espace réservé, tels que les symboles qui séparent les jours des heures, les heures des minutes ou les secondes des fractions de seconde. Au lieu de cela, ces symboles doivent être inclus dans la chaîne de format personnalisée en tant que littéraux de chaîne. Par exemple, "jj.hh: mm" définit un point (.) Comme séparateur entre les jours et les heures et un deux-points (:) comme séparateur entre les heures et les minutes.
myTimeSpan = new TimeSpan(15, 35, 54);
l'instruction myTimeSpan .ToString("hh\\mm\\ss");
se traduira par 15m35s54
. Je ne pense pas que ce soit ce que vous vouliez, car cela placera un m après vos heures et un s après vos minutes.
$"{myTimeSpan.TotalHours}:{myTimeSpan:mm\\:ss}"
. Du point de vue de l'utilisateur, il serait peut-être préférable d'afficher les jours, personne ne veut mentalement savoir combien de jours sont dans plus de 200 heures.
Pour .NET 3.5 et versions antérieures, vous pouvez utiliser:
string.Format ("{0:00}:{1:00}:{2:00}",
(int)myTimeSpan.TotalHours,
myTimeSpan.Minutes,
myTimeSpan.Seconds);
Code tiré d'une réponse de Jon Skeet sur les octets
Pour .NET 4.0 et supérieur, consultez la réponse de DoctaJonez .
Une façon est de créer un DateTime
objet et de l'utiliser pour le formatage:
new DateTime(myTimeSpan.Ticks).ToString(myCustomFormat)
// or using String.Format:
String.Format("{0:HHmmss}", new DateTime(myTimeSpan.Ticks))
C'est comme ça que je sais. J'espère que quelqu'un pourra suggérer une meilleure solution.
Facile. Utiliser TimeSpan.ToString
avec c, g ou G. Plus d'informations sur MSDN
J'irais avec
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"))
Cela fonctionne pour Framework 4
Personnellement, j'aime cette approche:
TimeSpan ts = ...;
string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", ts);
Vous pouvez le personnaliser comme vous le souhaitez sans aucun problème:
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);
Vous pouvez également utiliser:
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")
ÉDITER:
Vous pouvez également consulter 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");
Tous les caractères littéraux doivent être échappés.
J'ai utilisé le code ci-dessous. Il est long, mais il s'agit toujours d'une expression et produit une sortie très conviviale, car il ne génère pas de jours, heures, minutes ou secondes s'ils ont une valeur de zéro.
Dans l'exemple, il produit une sortie: "4 jours 1 heure 3 secondes".
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" : ""); }
Appelez cela pour chaque composant (par exemple timeComponent(sp.Days, "day")
), puis utilisez String.join
pour insérer les espaces.
J'utilise cette méthode. Je suis belge et parle néerlandais, donc le pluriel des heures et des minutes ne consiste pas seulement à ajouter des «s» à la fin, mais presque un mot différent du singulier.
Cela peut paraître long mais c'est très lisible je pense:
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
C'est l'approche que j'ai utilisée moi-même avec la mise en forme conditionnelle. et je le poste ici parce que je pense que c'est une manière propre.
$"{time.Days:#0:;;\\}{time.Hours:#0:;;\\}{time.Minutes:00:}{time.Seconds:00}"
exemple de sorties:
00:00
(le minimum)
1:43:04
(quand on a des heures)
15:03:01
(lorsque les heures sont supérieures à 1 chiffre)
2:4:22:04
(quand nous avons des jours.)
Le formatage est simple. time.Days:#0:;;\\
le format avant ;;
est pour quand la valeur est positive. les valeurs négatives sont ignorées. et pour les valeurs nulles, nous avons ;;\\
afin de le cacher dans une chaîne formatée. notez que la barre oblique inverse échappée est nécessaire sinon elle ne se formatera pas correctement.
Voici ma méthode d'extension :
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));
}
Exemple d'appel:
string time = new TimeSpan(3, 14, 15, 0, 65).ToFormattedString();
Production:
3 days, 14 hours, 15 minutes, 65 milliseconds
C'est une douleur dans VS 2010, voici ma solution de contournement.
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;
}
}
}
La Substring
méthode fonctionne parfaitement lorsque vous ne voulez que les heures: minutes: secondes. C'est un code simple, propre et facile à comprendre.
var yourTimeSpan = DateTime.Now - DateTime.Now.AddMinutes(-2);
var formatted = yourTimeSpan.ToString().Substring(0,8);// 00:00:00
Console.WriteLine(formatted);
Voici ma version. Il ne montre que ce qui est nécessaire, gère la pluralisation, les négatifs et j'ai essayé de le rendre léger.
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 vous voulez un format de durée similaire à YouTube, étant donné le nombre de secondes
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));
}
Production:
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
Je voulais renvoyer une chaîne telle que "1 jour 2 heures 3 minutes" et aussi prendre en compte si par exemple les jours ou les minutes sont à 0 et ne pas les afficher. merci à John Rasch pour sa réponse dont la mienne est à peine une extension 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 ");