.NET'te özel bir biçime sahip bir TimeSpan nesnesini nasıl String.Format yapabilirim?


Yanıtlar:


247

Lütfen dikkat: bu cevap .Net 4.0 ve üstü içindir. Time 3.5'i .Net 3.5 veya daha düşük bir sürümle biçimlendirmek istiyorsanız, lütfen JohannesH'nin cevabına bakın .

Özel TimeSpan biçimi dizeleri .Net 4.0'da tanıtıldı. MSDN Özel TimeSpan Biçim Dizeleri sayfasında kullanılabilir biçim belirteçlerinin tam referansını bulabilirsiniz .

Örnek bir zaman aralığı biçimi dizesi:

string.Format("{0:hh\\:mm\\:ss}", myTimeSpan); //example output 15:36:15

( UPDATE ) ve C # 6 dize enterpolasyonu kullanan bir örnek:

$"{myTimeSpan:hh\\:mm\\:ss}"; //example output 15:36:15

":" Karakterinden "\" karakteriyle (bir sözcük dizgisi kullanmadığınız sürece kendisinden kaçılması gerekir) kaçmanız gerekir.

MSDN Özel TimeSpan Biçim Dizeleri sayfasındaki bu alıntı ":" ve ". biçim dizesindeki karakterler:

Özel TimeSpan biçimi belirteçleri, günleri saatlerden saatlere, dakikalardan dakikalara veya saniyeleri kesirli saniyelerden ayıran semboller gibi yer tutucu ayırıcı sembolleri içermez. Bunun yerine, bu semboller özel biçim dizesine dize değişmezleri olarak dahil edilmelidir. Örneğin, "gg.şs: dd", gün ve saat arasında ayırıcı olarak bir nokta (.) Ve saat ve dakika arasında ayırıcı olarak iki nokta üst üste (:) tanımlar.


7
@Andrei Rinea: Doğru, ikinci paragrafımın başlangıcında belirtildiği gibi ".Net 4, Timespan ile özel biçim dizeleri kullanmanıza izin verir".
Doktor Jones

1
@Edward, bu pek doğru değil. Örneğinizde, ilk m ve ilk s'den kaçıyorsunuz, böylece myTimeSpan = new TimeSpan(15, 35, 54);ifadenin bir girişi ile myTimeSpan .ToString("hh\\mm\\ss");sonuçlanacaktır 15m35s54. Sanırım bu saatlerden sonra m, dakikalardan sonra m.
Doctor Jones

1
@ Doktor Jones - Teşekkürler! MyTimeSpan.ToString ("h \\ hm \\ ms \\ s"); veya myTimeSpan.ToString (@ "h \ hm \ ms \ s"); Bu 15h35m54s verir
Edward

2
sadece bu çözüme dikkat edin, çünkü Hours bölümü 24'ten fazla olduğunda doğru çalışmaz
Zoltan Tirinda

1
@QuarK, bunu yapan özel bir format belirleyici yoktur, hepsi size günlerin bir parçası olarak sayılmayan saatleri verir. Bunun yerine bunu yapabilirsiniz $"{myTimeSpan.TotalHours}:{myTimeSpan:mm\\:ss}". Bir kullanıcı bakış açısından, günleri çıkarmak daha iyi olabilir, ancak kimse zihinsel olarak 200'den fazla saat içinde kaç günün olduğunu anlamak istemez.
Doktor Jones

91

.NET 3.5 ve daha düşük sürümler için şunları kullanabilirsiniz:

string.Format ("{0:00}:{1:00}:{2:00}", 
               (int)myTimeSpan.TotalHours, 
                    myTimeSpan.Minutes, 
                    myTimeSpan.Seconds);

Kod bir Jon Skeet alınan cevap bayt üzerinde

.NET 4.0 ve üzeri için, DoctaJonez bkz cevabı .


Evet teşekkür ederim. Ancak DateTime tarafından desteklenen herhangi bir saat biçiminde çalışacağı için DateTime yaklaşımının daha özelleştirilebilir olduğunu düşünüyorum. Bu yaklaşımı örneğin AM / PM göstermek için kullanmak zordur.
Hosam Aly

1
Elbette, TimeSpan, günün bir zamanını değil, bir zamanı temsil eder (DateTime.Now.TimeOfDay özelliği aksini düşünmenize rağmen). Günün belirli bir saatini temsil etmeniz gerekiyorsa, DateTime sınıfını kullanmaya devam etmenizi öneririm.
JohannesH

7
TimeSpan 24 saat veya daha uzunsa yanlış biçimlendirme elde edeceğinizi unutmayın.
JohannesH

31

Bunun bir yolu bir DateTimenesne oluşturmak ve onu biçimlendirme için kullanmaktır:

new DateTime(myTimeSpan.Ticks).ToString(myCustomFormat)

// or using String.Format:
String.Format("{0:HHmmss}", new DateTime(myTimeSpan.Ticks))

Ben böyle biliyorum. Umarım birisi daha iyi bir yol önerebilir.


14
Bu gerçekten sadece TimeSpan bir günden az ise işe yarayacaktır. Bu böylesine korkunç bir kısıtlama olmayabilir, ancak genel bir çözüm olmasını engeller.
tvanfosson

Doğru değeri döndürüyor mu? Dim ts As New TimeSpan (11, 22, 30, 30): Dim sss As String = Yeni DateTime (ts.Ticks) .ToString ("dd.hh: mm: ss")
NeverHopeless

10

Basit. TimeSpan.ToStringC, g veya G ile kullanın . MSDN'de daha fazla bilgi


1
Cevabınız için teşekkür ederim. Bu yöntem görünüşe göre .NET 4'te yenidir ve soru sorulduğunda mevcut değildi. Özel biçimleri de desteklemez. Bununla birlikte, bu soruların cevaplarına değerli bir ektir. Tekrar teşekkürler.
Hosam Aly



5

Şahsen, bu yaklaşımı seviyorum:

TimeSpan ts = ...;
string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", ts);

Bunu herhangi bir sorun olmadan istediğiniz kadar özel yapabilirsiniz:

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);

5

Bu harika bir şey:

string.Format("{0:00}:{1:00}:{2:00}",
               (int)myTimeSpan.TotalHours,
               myTimeSpan.Minutes,
               myTimeSpan.Seconds);

1
MyTimeSpan.TotalHours öğesini bir int'e yayınlamanız gerekir - aksi takdirde yuvarlanabilir. JohannesH'nin cevabına bakınız
codeulike

3

Şunlarla da gidebilirsiniz:

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")

DÜZENLE:

Ayrıca Strings.Format'a da bakabilirsiniz .

    Dim ts As New TimeSpan(23, 30, 59)
    Dim str As String = Strings.Format(New DateTime(ts.Ticks), "H:mm:ss")

3
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");

Tüm gerçek karakterler kaçmalıdır.


1

Aşağıdaki kodu kullandım. Uzun, ama yine de tek bir ifadedir ve sıfır değerine sahipse günler, saatler, dakikalar veya saniyeler çıkmadığı için çok kolay çıktılar üretir.

Örnekte çıktı üretir: "4 gün 1 saat 3 saniye".

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);

Şimdi bunu yazmanın çok daha iyi bir yolu var! Tüm yaygın işlemleri yeniden düzenlemeye çalışın ve bu kodun çok daha iyi görünmesini sağlayabilirsiniz.
Hosam Aly

@Hosam Aly; Her zaman öğreniyorum, geliştirilmiş kodunuzu yayınlamak ister misiniz?
panpawel

String timeComponent(int value, String name) { return value > 0 ? value + " " + name + (value > 1 ? "s" : ""); }Her bileşen (örneğin timeComponent(sp.Days, "day")) için bunu çağırın , ardından String.joinboşlukları eklemek için kullanın .
Hosam Aly

1

Bu yöntemi kullanıyorum. Ben Belçikalıyım ve çok fazla saat ve dakika süren Hollandaca konuşuyor, sadece sonuna 's' eklemekle kalmıyor, aynı zamanda tekilden neredeyse farklı bir kelime.

Uzun görünebilir ama bence çok okunabilir:

 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

Çevrilmesi gereken bir yazılım yazarsanız, bu hemen hemen yoludur. Standart TimeSpan.ToString () normal son kullanıcıların anlayamayacakları kadar, özellikle de bir günden uzun süren aralıklarda.
Neil

1

Kendimi koşullu biçimlendirmeyle kullandığım yaklaşım bu. ve buraya gönderiyorum çünkü bunun temiz bir yol olduğunu düşünüyorum.

$"{time.Days:#0:;;\\}{time.Hours:#0:;;\\}{time.Minutes:00:}{time.Seconds:00}"

çıktılara örnek:

00:00 (En az)

1:43:04 (saatlerimiz olduğunda)

15:03:01 (saatler 1 basamaktan fazla olduğunda)

2:4:22:04 (günlerimiz olduğunda.)

Biçimlendirme kolaydır. time.Days:#0:;;\\önceki biçim ;;, değer pozitif olduğunda içindir. negatif değerler dikkate alınmaz. ve sıfır değerleri için ;;\\biçimlendirilmiş dizede gizlemek için elimizde . kaçan ters eğik çizginin gerekli olduğunu unutmayın, aksi takdirde düzgün biçimlendirilmez.


1

İşte benim uzantısı yöntemi :

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));
}

Örnek çağrı:

string time = new TimeSpan(3, 14, 15, 0, 65).ToFormattedString();

Çıktı:

3 days, 14 hours, 15 minutes, 65 milliseconds

1

Bu VS 2010'da bir acı, işte benim geçici çözümüm.

 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;
                }
            } 
        }

1

SubstringDakika: Saniye sadece Saat istediğinizde yöntem mükemmel çalışıyor. Basit, temiz kod ve anlaşılması kolaydır.

    var yourTimeSpan = DateTime.Now - DateTime.Now.AddMinutes(-2);

    var formatted = yourTimeSpan.ToString().Substring(0,8);// 00:00:00 

    Console.WriteLine(formatted);

0

İşte benim versiyonum. Sadece gerektiği kadar gösterir, çoğullaştırmayı, olumsuzlukları ele alır ve onu hafifletmeye çalıştım.

Çıktı Örnekleri

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

kod

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;
    }
}

0

Süre biçiminin youtube'a benzer olmasını istiyorsanız, saniye sayısı göz önüne alındığında

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));
}

Çıktı:

     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

0

"1 gün 2 saat 3 dakika" gibi bir dize döndürmek ve örneğin günler veya dakikalar 0 ise ve sonra bunları göstermiyorsa da dikkate almak istedim. John Rasch'a cevabım için teşekkür ederim, ki benimki

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 ");
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.