포맷 시간 범위가 24시간보다 큼
다음과 같이 몇 초를 TimeSpan 개체로 변환한다고 가정합니다.
Dim sec = 1254234568
Dim t As TimeSpan = TimeSpan.FromSeconds(sec)
TimeSpan 개체를 다음과 같은 형식으로 포맷하는 방법은 무엇입니까?
>105hr 56mn 47sec
내장 기능이 있습니까? 아니면 사용자 정의 기능을 작성해야 합니까?
가장 간단한 방법은 직접 포맷하는 것입니다.
return string.Format("{0}hr {1}mn {2}sec",
(int) span.TotalHours,
span.Minutes,
span.Seconds);
VB에서:
Public Shared Function FormatTimeSpan(span As TimeSpan) As String
Return String.Format("{0}hr {1}mn {2}sec", _
CInt(Math.Truncate(span.TotalHours)), _
span.Minutes, _
span.Seconds)
End Function
그들 중 누구도TimeSpan
.NET 4에서 포맷하면 더 간단해집니다.
2018년 10월 편집: C# 6/VB 14는 내 원래 답변의 첫 번째 코드 세그먼트보다 간단하거나 간단하지 않을 수 있는 보간 문자열을 도입했습니다.고맙게도, 보간을 위한 구문은 두 언어 모두에 대해 동일합니다: 이전.$
.
C# 6
TimeSpan t = new TimeSpan(105, 56, 47);
Console.WriteLine($"{(int)t.TotalHours}h {t:mm}mn {t:ss}sec");
비주얼 베이직 14
dim t As New TimeSpan(105, 56, 47)
Console.WriteLine($"{CInt(Math.Truncate(t.TotalHours))}h {t:mm}mn {t:ss}sec")
2021년 11월 편집:위의 답변은 긍정적인 경우에만 작동합니다.TimeSpan
다음보다 작거나 같은 음의 s 및 s-1
한 시간. 만약 당신이 부정적인 것을 가지고 있다면.TimeSpan
범위 내에(-1, 0]hr
수동으로 네거티브를 삽입해야 합니다.참고, 이는 원래 답변에도 해당됩니다.
TimeSpan t = TimeSpan.FromSeconds(-30 * 60 - 10); // -(30mn 10 sec)
Console.WriteLine($"{(ts.Ticks < 0 && (int)ts.TotalHours == 0 ? "-" : "")}{(int)t.TotalHours}h {t:mm}mn {t:ss}sec");
번거롭기 때문에 도우미 기능을 만드는 것을 추천합니다.
string Neg(TimeSpan ts)
{
return ts.Ticks < 0 && (int)ts.TotalHours == 0 ? "-" : "";
}
TimeSpan t = TimeSpan.FromSeconds(-30 * 60 - 10); // -(30mn 10 sec)
Console.WriteLine($"{Neg(ts)}{(int)t.TotalHours}h {t:mm}mn {t:ss}sec");
나는 동등한 버전을 쓸 만큼 VB를 잘 알지 못합니다.
C#7에 소개된 기능을 포함하여 C#의 간단한 예를 보십시오. 아아, 내가 찾을 수 있는 유일한 C#7 온라인 컴파일러는 .NET Core를 실행합니다. 이것은 작은 예제들에게는 매우 번거롭지만, .NET Framework 프로젝트에서도 정확히 동일하게 작동합니다.
원답
Microsoft에는 현재 이에 대한 단순 형식 문자열 바로 가기가 없습니다.가장 쉬운 옵션은 이미 공유되었습니다.
C#
string.Format("{0}hr {1:mm}mn {1:ss}sec", (int)t.TotalHours, t);
VB
String.Format("{0}hr {1:mm}mn {1:ss}sec", _
CInt(Math.Truncate(t.TotalHours)), _
t)
그러나 지나치게 철저한 옵션은 자체적으로 구현하는 것입니다.ICustomFormatter
위해서TimeSpan
장기적으로 시간을 절약할 수 있도록 자주 사용하지 않는 한 추천하지 않을 것입니다.하지만, 당신이 자신의 수업을 쓰는 경우가 있습니다.ICustomFormatter
적절하기 때문에, 저는 예를 들어 이것을 썼습니다.
/// <summary>
/// Custom string formatter for TimeSpan that allows easy retrieval of Total segments.
/// </summary>
/// <example>
/// TimeSpan myTimeSpan = new TimeSpan(27, 13, 5);
/// string.Format("{0:th,###}h {0:mm}m {0:ss}s", myTimeSpan) -> "27h 13m 05s"
/// string.Format("{0:TH}", myTimeSpan) -> "27.2180555555556"
///
/// NOTE: myTimeSpan.ToString("TH") does not work. See Remarks.
/// </example>
/// <remarks>
/// Due to a quirk of .NET Framework (up through version 4.5.1),
/// <code>TimeSpan.ToString(format, new TimeSpanFormatter())</code> will not work; it will always call
/// TimeSpanFormat.FormatCustomized() which takes a DateTimeFormatInfo rather than an
/// IFormatProvider/ICustomFormatter. DateTimeFormatInfo, unfortunately, is a sealed class.
/// </remarks>
public class TimeSpanFormatter : IFormatProvider, ICustomFormatter
{
/// <summary>
/// Used to create a wrapper format string with the specified format.
/// </summary>
private const string DefaultFormat = "{{0:{0}}}";
/// <remarks>
/// IFormatProvider.GetFormat implementation.
/// </remarks>
public object GetFormat(Type formatType)
{
// Determine whether custom formatting object is requested.
if (formatType == typeof(ICustomFormatter))
{
return this;
}
return null;
}
/// <summary>
/// Determines whether the specified format is looking for a total, and formats it accordingly.
/// If not, returns the default format for the given <para>format</para> of a TimeSpan.
/// </summary>
/// <returns>
/// The formatted string for the given TimeSpan.
/// </returns>
/// <remarks>
/// ICustomFormatter.Format implementation.
/// </remarks>
public string Format(string format, object arg, IFormatProvider formatProvider)
{
// only apply our format if there is a format and if the argument is a TimeSpan
if (string.IsNullOrWhiteSpace(format) ||
formatProvider != this || // this should always be true, but just in case...
!(arg is TimeSpan) ||
arg == null)
{
// return the default for whatever our format and argument are
return GetDefault(format, arg);
}
TimeSpan span = (TimeSpan)arg;
string[] formatSegments = format.Split(new char[] { ',' }, 2);
string tsFormat = formatSegments[0];
// Get inner formatting which will be applied to the int or double value of the requested total.
// Default number format is just to return the number plainly.
string numberFormat = "{0}";
if (formatSegments.Length > 1)
{
numberFormat = string.Format(DefaultFormat, formatSegments[1]);
}
// We only handle two-character formats, and only when those characters' capitalization match
// (e.g. 'TH' and 'th', but not 'tH'). Feel free to change this to suit your needs.
if (tsFormat.Length != 2 ||
char.IsUpper(tsFormat[0]) != char.IsUpper(tsFormat[1]))
{
return GetDefault(format, arg);
}
// get the specified time segment from the TimeSpan as a double
double valAsDouble;
switch (char.ToLower(tsFormat[1]))
{
case 'd':
valAsDouble = span.TotalDays;
break;
case 'h':
valAsDouble = span.TotalHours;
break;
case 'm':
valAsDouble = span.TotalMinutes;
break;
case 's':
valAsDouble = span.TotalSeconds;
break;
case 'f':
valAsDouble = span.TotalMilliseconds;
break;
default:
return GetDefault(format, arg);
}
// figure out if we want a double or an integer
switch (tsFormat[0])
{
case 'T':
// format Total as double
return string.Format(numberFormat, valAsDouble);
case 't':
// format Total as int (rounded down)
return string.Format(numberFormat, (int)valAsDouble);
default:
return GetDefault(format, arg);
}
}
/// <summary>
/// Returns the formatted value when we don't know what to do with their specified format.
/// </summary>
private string GetDefault(string format, object arg)
{
return string.Format(string.Format(DefaultFormat, format), arg);
}
}
참고로, 코드에 있는 언급처럼,TimeSpan.ToString(format, myTimeSpanFormatter)
.NET Framework의 특성으로 인해 작동하지 않으므로 항상 문자열을 사용해야 합니다.이 클래스를 사용할 형식(format, myTimeSpanFormatter)입니다.DateTime용 사용자 지정 IFormatProvider를 만들고 사용하는 방법을 참조하십시오.
편집: 정말로, 제 말은, 정말로, 이것이 작동하기를 바란다면,TimeSpan.ToString(string, TimeSpanFormatter)
은 위의 다추수가있에 할 수 .TimeSpanFormatter
명령어:
/// <remarks>
/// Update this as needed.
/// </remarks>
internal static string[] GetRecognizedFormats()
{
return new string[] { "td", "th", "tm", "ts", "tf", "TD", "TH", "TM", "TS", "TF" };
}
그리고 다음 클래스를 동일한 네임스페이스의 어딘가에 추가합니다.
public static class TimeSpanFormatterExtensions
{
private static readonly string CustomFormatsRegex = string.Format(@"([^\\])?({0})(?:,{{([^(\\}})]+)}})?", string.Join("|", TimeSpanFormatter.GetRecognizedFormats()));
public static string ToString(this TimeSpan timeSpan, string format, ICustomFormatter formatter)
{
if (formatter == null)
{
throw new ArgumentNullException();
}
TimeSpanFormatter tsFormatter = (TimeSpanFormatter)formatter;
format = Regex.Replace(format, CustomFormatsRegex, new MatchEvaluator(m => MatchReplacer(m, timeSpan, tsFormatter)));
return timeSpan.ToString(format);
}
private static string MatchReplacer(Match m, TimeSpan timeSpan, TimeSpanFormatter formatter)
{
// the matched non-'\' char before the stuff we actually care about
string firstChar = m.Groups[1].Success ? m.Groups[1].Value : string.Empty;
string input;
if (m.Groups[3].Success)
{
// has additional formatting
input = string.Format("{0},{1}", m.Groups[2].Value, m.Groups[3].Value);
}
else
{
input = m.Groups[2].Value;
}
string replacement = formatter.Format(input, timeSpan, formatter);
if (string.IsNullOrEmpty(replacement))
{
return firstChar;
}
return string.Format("{0}\\{1}", firstChar, string.Join("\\", replacement.ToCharArray()));
}
}
이 후에는 다음을 사용할 수 있습니다.
ICustomFormatter formatter = new TimeSpanFormatter();
string myStr = myTimeSpan.ToString(@"TH,{000.00}h\:tm\m\:ss\s", formatter);
{000.00}
총 시간 int 또는 더블 형합니다지정식을▁total다니▁hours▁int합또지.문자열에 포함되지 않아야 하는 괄호를 확인합니다.형식() 대/소문자입니다. 참로고.formatter
다음과 같이 선언(또는 캐스팅)해야 합니다.ICustomFormatter
TimeSpanFormatter
.
과도하다고요?네. 대단하다고요?어...
string.Format("{0}hr {1}mn {2}sec", (int) t.TotalHours, t.Minutes, t.Seconds);
사용해 볼 수 있습니다.
TimeSpan ts = TimeSpan.FromSeconds(1254234568);
Console.WriteLine($"{((int)ts.TotalHours).ToString("d2")}hr {ts.Minutes.ToString("d2")}mm {ts.Seconds.ToString("d2")}sec");
(https://msdn.microsoft.com/en-us/library/1ecy8h51(v=vs.110).aspx), 에 따르면 TimeSpan 개체에 대한 기본 ToString() 메서드는 "c" 형식을 사용합니다. 즉, 기본적으로 24시간보다 긴 시간은 레이저 뷰로 출력할 때 "1.03:14:56"과 같이 보입니다.이로 인해 "1"이 하루를 나타내는 것을 이해하지 못하는 고객들과 혼동을 일으켰습니다.
그래서 만약 당신이 보간된 문자열(C#6+)을 사용할 수 있다면, 일+ 대신 총 시간을 사용하면서 기본 형식을 최대한 보존할 수 있는 쉬운 방법을 생각해 냈습니다.Hours는 다음과 같이 형식화된 문자열로 시간을 출력할 get 속성을 제공합니다.
public TimeSpan SystemTime { get; set; }
public string SystemTimeAsString
{
get
{
// Note: ignoring fractional seconds.
return $"{(int)SystemTime.TotalHours}:SystemTime.Minutes.ToString("00")}:SystemTime.Seconds.ToString("00")}";
}
}
위와 같은 시간을 사용한 결과는 "27:14:56"입니다.
시간을 계산해야 할 수도 있습니다.시간 범위(시간 범위)의 범위입니다.ToString은 0-23입니다.
가장 필요한 것은 존 스키트라는 이름의 원시 문자열 형식을 만드는 것입니다.
이 기능을 사용해 보십시오.
Public Shared Function GetTimeSpanString(ByVal ts As TimeSpan) As String
Dim output As New StringBuilder()
Dim needsComma As Boolean = False
If ts = Nothing Then
Return "00:00:00"
End If
If ts.TotalHours >= 1 Then
output.AppendFormat("{0} hr", Math.Truncate(ts.TotalHours))
If ts.TotalHours > 1 Then
output.Append("s")
End If
needsComma = True
End If
If ts.Minutes > 0 Then
If needsComma Then
output.Append(", ")
End If
output.AppendFormat("{0} m", ts.Minutes)
'If ts.Minutes > 1 Then
' output.Append("s")
'End If
needsComma = True
End If
Return output.ToString()
End Function
Noda Time's를 사용하는 것을 고려해 보는 것이 좋습니다.Duration
활자를
예:
Duration d = Duration.FromSeconds(sec);
또는
Duration d = Duration.FromTimeSpan(ts);
그런 다음 다음 다음과 같이 간단히 문자열 형식을 지정할 수 있습니다.
string result = d.ToString("H'hr' m'mn' s'sec'", CultureInfo.InvariantCulture);
대신 패턴 기반 API를 사용할 수 있습니다.
DurationPattern p = DurationPattern.CreateWithInvariantCulture("H'hr' m'mn' s'sec'");
string result = p.Format(d);
패턴 API의 장점은 패턴을 한 번만 만들면 된다는 것입니다.구문 분석하거나 형식을 지정할 값이 많은 경우 상당한 성능 이점이 있을 수 있습니다.
내 솔루션은 다음과(와)
string text = Math.Floor(timeUsed.TotalHours) + "h " + ((int)timeUsed.TotalMinutes) % 60 + "min";
MS Excel에는 .NET과 다른 형식이 있습니다.
이 링크를 확인하십시오. http://www.paragon-inc.com/resources/blogs-posts/easy_excel_interaction_pt8
MS Excel 형식으로 DateTime의 TimeSpan을 변환하는 간단한 함수를 만듭니다.
public static DateTime MyApproach(TimeSpan time)
{
return new DateTime(1900, 1, 1).Add(time).AddDays(-2);
}
그리고 다음과 같이 셀을 포맷해야 합니다.
col.Style.Numberformat.Format = "[H]:mm:ss";
언급URL : https://stackoverflow.com/questions/3505230/format-timespan-greater-than-24-hour
'source' 카테고리의 다른 글
왜 파이썬 3.4에 비해 파이썬 3.5에서 str.translate가 훨씬 빠릅니까? (0) | 2023.05.17 |
---|---|
.NET에서 시간 전용 값을 어떻게 표시합니까? (0) | 2023.05.17 |
iOS11/Xcode 9에서 TIC 읽기 상태 1:57은 무엇입니까? (0) | 2023.05.17 |
#c#에서 디버그가 아닌 경우? (0) | 2023.05.17 |
mongoose 스키마 생성 (0) | 2023.05.17 |