.NET에서 TimeSpan 객체를 사용자 정의 형식으로 String.Format하려면 어떻게해야합니까?


답변:


247

참고 :이 답변은 .Net 4.0 이상입니다. .Net 3.5 이하에서 TimeSpan을 포맷하려면 JohannesH의 답변을 참조하십시오 .

사용자 지정 TimeSpan 형식 문자열은 .Net 4.0에서 도입되었습니다. MSDN Custom TimeSpan Format Strings 페이지 에서 사용 가능한 형식 지정자에 대한 전체 참조를 찾을 수 있습니다 .

다음은 타임스 팬 형식 문자열의 예입니다.

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

( UPDATE ) 다음은 C # 6 문자열 보간을 사용하는 예입니다.

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

":"문자를 "\"로 이스케이프해야합니다 (자체 문자열을 사용하지 않는 한 이스케이프해야합니다).

MSDN Custom TimeSpan Format Strings 페이지 에서 발췌 한 ":"및 ". 형식 문자열의 문자 :

사용자 정의 TimeSpan 형식 지정자에는 일을 시간, 시간, 분 또는 초를 소수 초로 분리하는 기호와 같은 자리 표시 자 구분 기호가 포함되지 않습니다. 대신 이러한 기호는 사용자 정의 형식 문자열에 문자열 리터럴로 포함되어야합니다. 예를 들어 "dd.hh : mm"은 일과 시간 사이의 구분 기호로 마침표 (.)를 정의하고 시간과 분 사이의 구분 기호로 콜론 (:)을 정의합니다.


7
@Andrei Rinea : 두 번째 단락 ".Net 4에서는 Timespan과 함께 사용자 지정 형식 문자열을 사용할 수 있습니다."
닥터 존스

1
@ 에드워드, 그건 옳지 않습니다. 귀하의 예에서 첫 번째 m과 첫 번째 m을 이스케이프 처리하므로 myTimeSpan = new TimeSpan(15, 35, 54);명령문 myTimeSpan .ToString("hh\\mm\\ss");을 입력 하면 결과가됩니다 15m35s54. 나는 그것이 당신이 의도 한 시간이라고 생각하지 않습니다. 시간 후에 m을, 분 후에 s를 배치 할 것입니다.
닥터 존스

1
@Doctor Jones-감사합니다! myTimeSpan.ToString ( "h \\ hm \\ ms \\ s"); 또는 myTimeSpan.ToString (@ "h \ hm \ ms \ s"); 에 15h35m54s 제공
에드워드

2
시간 부분이 24보다 클 때 제대로 작동하지
않으므로이

1
@QuarK, 사용자 지정 형식 지정자가 없으므로 일의 일부로 계산되지 않은 시간을 제공합니다. 당신은 대신에 이것을 할 수 $"{myTimeSpan.TotalHours}:{myTimeSpan:mm\\:ss}"있습니다. 사용자 관점에서 볼 때 요일을 출력하는 것이 더 좋을 것입니다. 아무도 200 시간 이상의 요일을 정신적으로 파악하고 싶지는 않습니다.
닥터 존스

91

.NET 3.5 이하의 경우 다음을 사용할 수 있습니다.

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

바이트에 대한 Jon Skeet 답변 에서 가져온 코드

.NET 4.0 이상의 경우 DoctaJonez answer를 참조하십시오 .


네 감사합니다. 그러나 DateTime 방식은 DateTime이 지원하는 모든 시간 형식에서 작동하므로 더 사용자 정의가 가능하다고 생각합니다. 이 방법은 예를 들어 AM / PM을 표시하는 데 사용하기가 어렵습니다.
Hosam Aly

1
물론, TimeSpan은 시간이 아닌 기간을 나타 내기위한 것입니다 (DateTime.Now.TimeOfDay 속성이 다르게 생각하더라도). 특정 시간을 나타내려면 DateTime 클래스를 계속 사용하는 것이 좋습니다.
JohannesH

7
TimeSpan이 24 시간 이상이면 서식이 잘못됩니다.
JohannesH

31

한 가지 방법은 DateTime객체 를 만들어서 서식을 지정하는 것입니다.

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

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

이것이 내가 아는 방법입니다. 누군가가 더 나은 방법을 제안 할 수 있기를 바랍니다.


14
TimeSpan이 하루 미만인 경우에만 실제로 작동합니다. 그렇게 끔찍한 제한은 아니지만 일반적인 해결책은 아닙니다.
tvanfosson

올바른 값을 반환합니까? New TimeSpan (11, 22, 30, 30)으로 희미하게하기 : Dim sss As String = New DateTime (ts.Ticks) .ToString ( "dd.hh : mm : ss")
NeverHopeless

10

단순한. TimeSpan.ToStringc, g 또는 G와 함께 사용 하십시오. MSDN의 추가 정보


1
답변 주셔서 감사합니다. 이 방법은 .NET 4에서 새로 도입되었으며 질문을 받았을 때는 없었습니다. 또한 사용자 정의 형식을 지원하지 않습니다. 그럼에도 불구하고이 질문에 대한 답변에 귀중한 추가 사항입니다. 다시 감사합니다.
Hosam Aly

8

나는 갈 것이다

myTimeSpan.ToString("hh\\:mm\\:ss");

간단하고 깨끗합니다! 대안은 @ "hh \ : mm \ : ss"입니다.
Xilmiki


5

개인적으로, 나는이 접근법을 좋아한다 :

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

아무 문제없이 원하는대로 사용자 정의 할 수 있습니다.

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

이것은 굉장한 것입니다 :

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

1
myTimeSpan.TotalHours를 int로 캐스트해야합니다. 그렇지 않으면 반올림 될 수 있습니다.
codeulike

3

당신은 또한 함께 갈 수 있습니다 :

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

편집하다:

Strings.Format 도 볼 수 있습니다 .

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

모든 리터럴 문자는 이스케이프되어야합니다.


1

아래 코드를 사용했습니다. 길지만 여전히 하나의 표현식이며 값이 0 인 경우 일, 시간, 분 또는 초를 출력하지 않으므로 매우 친숙한 출력을 생성합니다.

샘플에서는 "4 일 1 시간 3 초"출력을 생성합니다.

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

이제 이것을 작성하는 훨씬 더 좋은 방법이 있습니다! 모든 공통 작업을 리팩토링하려고하면이 코드를 훨씬 더 잘 보이게 만들 수 있습니다.
Hosam Aly

@ 호삼 알리; 항상 배우고 있습니다. 개선 된 코드를 게시 하시겠습니까?
panpawel

String timeComponent(int value, String name) { return value > 0 ? value + " " + name + (value > 1 ? "s" : ""); }각 구성 요소 (예 :)에 대해이를 호출 timeComponent(sp.Days, "day")한 다음 String.join공백을 삽입하는 데 사용하십시오.
Hosam Aly

1

이 방법을 사용합니다. 나는 벨기에 사람이고 네덜란드어를 말하고 있기 때문에 시간과 분의 복수는 끝에 's'를 추가하는 것이 아니라 단수와 거의 다른 단어를 추가합니다.

오래 걸리는 것 같지만 매우 읽기 쉽습니다.

 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

번역이 필요한 소프트웨어를 작성한다면, 이것은 거의 갈 길입니다. 표준 TimeSpan.ToString ()은 일반 최종 사용자가 이해하기에는 너무 복잡합니다. 특히 하루 이상 지속되는 경우 특히 그렇습니다.
Neil

1

이것은 조건부 서식과 함께 내 자신을 사용하는 접근 방식입니다. 나는 이것이 깨끗한 방법이라고 생각하기 때문에 여기에 게시합니다.

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

출력 예 :

00:00 (최저한의)

1:43:04 (시간이있을 때)

15:03:01 (시간이 1 자리 이상인 경우)

2:4:22:04 (날이있을 때)

서식이 쉽습니다. 값이 양수일 때 time.Days:#0:;;\\의 형식 ;;입니다. 음수 값은 무시됩니다. 값이 0 인 경우 ;;\\형식화 된 문자열에서 값 을 숨길 수 있습니다. 이스케이프 된 백 슬래시는 필요하며 그렇지 않으면 올바르게 포맷되지 않습니다.


1

확장 방법 은 다음과 같습니다 .

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

호출 예 :

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

산출:

3 days, 14 hours, 15 minutes, 65 milliseconds

1

이것은 VS 2010의 고통입니다. 여기 내 해결 방법이 있습니다.

 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

Substring방법은 Hours : Minutes : Seconds 만 원하는 경우 완벽하게 작동합니다. 간단하고 깔끔한 코드이며 이해하기 쉽습니다.

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

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

    Console.WriteLine(formatted);

0

여기 내 버전이 있습니다. 그것은 필요한만큼만 보여주고, 복수화, 부정을 처리하고, 그것을 가볍게 만들려고 노력했습니다.

출력 예

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

0

초 단위로 YouTube와 유사한 지속 시간 형식을 원할 경우

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

산출:

     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 일 2 시간 3 분"과 같은 문자열을 반환하고 싶고 예를 들어 일 또는 분이 0 인 경우를 고려한 다음 표시하지 않습니다. 존 라쉬 (John Rasch) 덕분 에

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 ");
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.