trabajadas sumar restar horas diferencia contar como calcular c# vb.net formatting timespan

sumar - restar timespan c#



Formato TimeSpan mayor a 24 horas (10)

Bueno, lo más simple es formatearlo usted mismo, por ejemplo

return string.Format("{0}hr {1}mn {2}sec", (int) span.TotalHours, span.Minutes, span.Seconds);

En 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

No sé si alguno de los formatos de TimeSpan en .NET 4 lo simplificaría.

Digamos que convierto algunos segundos en el objeto TimeSpan como este:

Dim sec = 1254234568 Dim t As TimeSpan = TimeSpan.FromSeconds(sec)

¿Cómo puedo formatear el objeto TimeSpan en un formato como el siguiente?

>105hr 56mn 47sec

¿Hay una función incorporada o debo escribir una función personalizada?


Es posible que necesite calcular las horas. El rango de horas en TimeSpan.ToString es solo 0-23.

Lo peor que necesitará es hacer un formato de cadena sin procesar a la Jon Skeet.


MS Excel tiene otro formato diferente a .NET.

Consulte este enlace http://www.paragon-inc.com/resources/blogs-posts/easy_excel_interaction_pt8

Creé una función simple que convierte un TimeSpan en un DateTime con el formato MS Excel

public static DateTime MyApproach(TimeSpan time) { return new DateTime(1900, 1, 1).Add(time).AddDays(-2); }

y debe formatear la celda de esta manera:

col.Style.Numberformat.Format = "[H]:mm:ss";


Mi solución es:

string text = Math.Floor(timeUsed.TotalHours) + "h " + ((int)timeUsed.TotalMinutes) % 60 + "min";


Microsoft no tiene (actualmente) un atajo de cadena de formato simple para esto. Las opciones más fáciles ya han sido compartidas.

string.Format("{0}hr {1:mm}mn {1:ss}sec", (int)t.TotalHours, t);

Sin embargo, una opción demasiado minuciosa es implementar su propio ICustomFormatter para TimeSpan . No lo recomendaría a menos que lo use con tanta frecuencia que le ahorre tiempo a largo plazo. Sin embargo, hay ocasiones en que HACE una clase en la que escribir su propio ICustomFormatter es apropiado, así que escribí este como ejemplo.

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

Tenga en cuenta que, como en los comentarios en el código, TimeSpan.ToString(format, myTimeSpanFormatter) no funcionará debido a una peculiaridad de .NET Framework, por lo que siempre tendrá que usar string.Format (format, myTimeSpanFormatter) para usar esto clase. Consulte Cómo crear y usar un IFormatProvider personalizado para DateTime? .


EDITAR : Si realmente, y quiero decir realmente , quiere que esto funcione con TimeSpan.ToString(string, TimeSpanFormatter) , puede agregar lo siguiente a la clase TimeSpanFormatter anterior:

/// <remarks> /// Update this as needed. /// </remarks> internal static string[] GetRecognizedFormats() { return new string[] { "td", "th", "tm", "ts", "tf", "TD", "TH", "TM", "TS", "TF" }; }

Y agrega la siguiente clase en algún lugar del mismo espacio de nombres:

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

Después de esto, puedes usar

ICustomFormatter formatter = new TimeSpanFormatter(); string myStr = myTimeSpan.ToString(@"TH,{000.00}h/:tm/m/:ss/s", formatter);

donde {000.00} es, sin embargo, desea que se formatee TotalHours int o double. Tenga en cuenta las llaves adjuntas, que no deberían estar allí en la cadena. Caso de formato (). También tenga en cuenta que el formatter debe declararse (o ICustomFormatter ) como ICustomFormatter lugar de TimeSpanFormatter .

¿Excesivo? Sí. ¿Increíble? Uhhh ....


Prueba esta función:

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

Convertir un Timespan en horas y minutos


Puede considerar usar el tipo de Duration Noda Time .

Por ejemplo:

Duration d = Duration.FromSeconds(sec);

O

Duration d = Duration.FromTimeSpan(ts);

A continuación, simplemente puede formatearlo como una cadena, como esta:

string result = d.ToString("H''hr'' m''mn'' s''sec''", CultureInfo.InvariantCulture);

Alternativamente, puede usar la API basada en patrones en su lugar:

DurationPattern p = DurationPattern.CreateWithInvariantCulture("H''hr'' m''mn'' s''sec''"); string result = p.Format(d);

La ventaja con el patrón API es que solo necesita crear el patrón una vez. Si tiene muchos valores para analizar o formatear, puede haber un beneficio significativo en el rendimiento.


Puedes intentar esto:

TimeSpan ts = TimeSpan.FromSeconds(1254234568); Console.WriteLine($"{((int)ts.TotalHours).ToString("d2")}hr {ts.Minutes.ToString("d2")}mm {ts.Seconds.ToString("d2")}sec");


Según ( https://msdn.microsoft.com/en-us/library/1ecy8h51(v=vs.110).aspx ), el método predeterminado ToString () para un objeto TimeSpan utiliza el formato "c", lo que significa que, de forma predeterminada, un intervalo de tiempo superior a 24 horas se parece a "1.03: 14: 56" cuando se envía a una vista de maquinilla de afeitar. Esto causó cierta confusión con mis clientes que no entienden que el "1". representa un día

Por lo tanto, si puede usar cadenas interpoladas (C # 6 +), una manera fácil que surgió para preservar el formato predeterminado tanto como sea posible, al usar TotalHours en lugar de Days + Hours es proporcionar una propiedad get para generar el hora como una cadena formateada, como así:

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

El resultado de esto usando el mismo tiempo que el anterior será "27:14:56".


string.Format("{0}hr {1}mn {2}sec", (int) t.TotalHours, t.Minutes, t.Seconds);