programing

줄을 어떻게 매야 합니까?에서 사용자 지정 형식으로 TimeSpan 개체를 포맷합니다.NET?

newstyles 2023. 8. 22. 22:00

줄을 어떻게 매야 합니까?에서 사용자 지정 형식으로 TimeSpan 개체를 포맷합니다.NET?

권장되는 포맷 방법은 무엇입니까?TimeSpan사용자 지정 형식을 사용하여 개체를 문자열로 변환하시겠습니까?

참고: 이 답변은 에 대한 것입니다.넷 4.0 이상.에서 시간 범위를 포맷하려는 경우.Net 3.5 이하는 Johannes를 참조하십시오.H의 대답.

사용자 지정 시간 범위 형식 문자열은 에 도입되었습니다.넷 4.0.MSDN 사용자 지정 시간 범위 형식 문자열 페이지에서 사용 가능한 형식 지정자에 대한 전체 참조를 찾을 수 있습니다.

다음은 시간 범위 형식 문자열의 예입니다.

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 사용자 지정 시간 범위 형식 문자열 페이지에서 발췌한 이 절에서는 형식 문자열의 ":" 및 "." 문자를 이스케이프하는 방법에 대해 설명합니다.

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

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

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

Jon Skeet 응답에서 가져온 바이트 코드

.NET 4.0 이상의 경우 DoctaJones 답변을 참조하십시오.

한 가지 방법은 다음을 만드는 것입니다.DateTime개체를 지정하고 형식 지정에 사용합니다.

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

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

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

순단. 용사를 사용합니다.TimeSpan.ToStringc, g 또는 G를 사용합니다. MSDN에서 더 많은 정보

저는 찬성합니다.

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

개인적으로, 저는 다음과 같은 접근 방식을 좋아합니다.

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);
Dim duration As New TimeSpan(1, 12, 23, 62)

DEBUG.WriteLine("Time of Travel: " + duration.ToString("dd\.hh\:mm\:ss"))

Framework 4에서 작동합니다.

http://msdn.microsoft.com/en-us/library/ee372287.aspx

이것은 멋진 것입니다.

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

다음과 같은 작업도 수행할 수 있습니다.

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

편집:

문자열도 볼 있습니다.포맷.

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

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

이것은 제가 조건부 서식을 가지고 제 자신을 사용한 접근법입니다.여기에 올리는 이유는 이게 깨끗한 방법이라고 생각하기 때문입니다.

$"{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의 가치에 대해 우리는 가지고 있습니다.;;\\형식화된 문자열로 숨기기 위해.이스케이프 백슬래시가 필요합니다. 그렇지 않으면 올바르게 포맷되지 않습니다.

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

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

저는 아래 코드를 사용했습니다.값이 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);

저는 이 방법을 사용합니다.저는 벨기에 사람이고 네덜란드어를 사용하기 때문에 시간과 분의 복수는 단순히 끝에 '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

이 문제는 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;
                }
            } 
        }

Substring시간:분:만 원하는 경우 메소드가 완벽하게 작동합니다.몇 초.간단하고 깨끗한 코드이며 이해하기 쉽습니다.

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

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

    Console.WriteLine(formatted);

특히 문자열 보간과 함께 사용할 때 내가 가장 좋아하는 10진수 형식 지정자로 접근하는 방법을 보여준 사람은 아무도 없습니다 - https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings?redirectedfrom=MSDN#decimal-format-specifier-d

예:

$"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{time.Milliseconds:D3}"
// Sample output: 00:00:09.200

물론 도우미 방식으로 포장할 수 있습니다.

여기 제 버전이 있습니다.그것은 필요한 만큼만 보여주고, 복수화, 부정화를 처리하고, 저는 그것을 경량화하려고 노력했습니다.

출력 예제

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

유튜브와 유사한 기간 형식을 원하는 경우(초)

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

"1일 2시간 3분"과 같은 문자열을 반환하고 일 또는 분이 0인 경우 표시되지 않는 경우도 고려하려고 합니다.래쉬의 답변에 감사드립니다. 저의 답변은 거의 연장이 되지 않습니다.

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

언급URL : https://stackoverflow.com/questions/574881/how-can-i-string-format-a-timespan-object-with-a-custom-format-in-net