2010-04-28 27 views
22

Cómo analizar cadena como 30:15 a TimeSpan en C#? 30:15 significa 30 horas y 15 minutos.Cómo analizar cadenas con horas superiores a 24 en TimeSpan?

string span = "30:15"; 
TimeSpan ts = TimeSpan.FromHours(
    Convert.ToDouble(span.Split(':')[0])). 
    Add(TimeSpan.FromMinutes(
    Convert.ToDouble((span.Split(':')[1])))); 

Esto no parece demasiado elegante.

+0

¿Es necesario apoyar la localización? (por ejemplo, 30.15 de acuerdo con la configuración de idioma) –

+0

El formato siempre será hh: mm, pero hh puede ser> 24. – jlp

+0

Ver esta [pregunta] (http://stackoverflow.com/questions/26760/c-parse-string -to-timespan) (duplicado). – Ando

Respuesta

24

Si está seguro de que el formato será siempre "hh: mm" vuelva a intentar algo como esto:

string span = "35:15"; 
TimeSpan ts = new TimeSpan(int.Parse(span.Split(':')[0]), // hours 
          int.Parse(span.Split(':')[1]), // minutes 
          0);        // seconds 
+0

feo, pero supongo que esa es la manera de hacerlo. gracias – invalidusername

+2

esto no funciona con un intervalo de tiempo negativo (-35: 15 daría como resultado -34: 45) – fubo

+0

bien C# TimeSpan funciona, pero ¿cómo almacenaría este valor en MSSQL? El tiempo (7) no funciona y la cuerda no sería tan agradable. – MaxW

0

Normalmente se usaría TimeSpan.ParseExact donde se requiere un formato específico. Pero los únicos formatos de horas que se pueden especificar son como partes de días (consulte Custom TimeSpan Format Strings).

Por lo tanto usted tendrá que hacer el trabajo usted mismo:

string input = "30:24"; 
var parts = input.Split(':'); 
var hours = Int32.Parse(parts[0]); 
var minutes = Int32.Parse(parts[1]); 
var result = new TimeSpan(hours, minutes, 0); 

(Pero con un poco de comprobación de errores.)

El constructor de tres entero de lapso de tiempo permite horas> = 24 desbordar en el recuento de días.

4

similares a la respuesta de Lucas:

String span = "123:45"; 
Int32 colon = span.IndexOf(':'); 
TimeSpan timeSpan = new TimeSpan(Int32.Parse(span.Substring(0, colon - 1)), 
           Int32.Parse(span.Substring(colon + 1)), 0); 

Obviamente asume está bien formado la cadena original (compuesto de dos partes separadas por dos puntos y parsable a un número entero).

+0

Creo que las manijas de Luke> 99 ¿no? – jlp

+0

@Erik, @jlp: Sí, el mío maneja horas superiores a 99 bien, aunque mi respuesta original no (antes edité hace media hora). Quizás Erik estaba mirando la respuesta anterior. – LukeH

+0

@Luke: ¡Sí!Exactamente como respondiste aquí;) –

3

estoy usando un método sencillo que ideé hace mucho tiempo y acaba de publicar hoy a mi blog:

public static class TimeSpanExtensions 
{ 
    static int[] weights = { 60 * 60 * 1000, 60 * 1000, 1000, 1 }; 

    public static TimeSpan ToTimeSpan(this string s) 
    { 
     string[] parts = s.Split('.', ':'); 
     long ms = 0; 
     for (int i = 0; i < parts.Length && i < weights.Length; i++) 
      ms += Convert.ToInt64(parts[i]) * weights[i]; 
     return TimeSpan.FromMilliseconds(ms); 
    } 
} 

Esto puede manejar una gran cantidad más situaciones que las soluciones más simples proporcionados antes, pero tiene su propias deficiencias. Lo discuto más lejos here.

Ahora, si estás en .NET 4 se puede acortar la ejecución ToTimeSpan a:

public static TimeSpan ToTimeSpan(this string s) 
{ 
    return TimeSpan.FromMilliseconds(s.Split('.', ':') 
     .Zip(weights, (d, w) => Convert.ToInt64(d) * w).Sum()); 
} 

Incluso puede que sea una sola línea si no les importa usar estado horizontal de la pantalla ..

+0

La solución está bien si el problema es exactamente como se describe en la pregunta. Pero si el valor de la cadena TimeSpan es como "1.06: 00: 00", esta solución falla. Lamentablemente, el enlace que explica las deficiencias no está funcionando. Meybe este tema se discute allí. – Florian

+0

@Florian Moveré mi blog a un nuevo (y mejor) host, ¡por eso está fuera de línea por ahora! No admite días, solo horas. Entonces, si quieres 24 + 6 horas, tendrás que usar 30:00:00. La idea era evitar usar días por completo. Las deficiencias tienen más que ver con no apoyar los valores negativos ... – Loudenvier

1

Similar a la respuesta de Lukes, con mucho más código y margen de mejora. PERO trata con Horas negativas ("-30: 15") también, así que tal vez pueda ayudar a alguien.

public static double GetTotalHours(String s) 
    { 
     bool isNegative = false; 
     if (s.StartsWith("-")) 
      isNegative = true; 

     String[] splitted = s.Split(':'); 
     int hours = GetNumbersAsInt(splitted[0]); 
     int minutes = GetNumbersAsInt(splitted[1]); 

     if (isNegative) 
     { 
      hours = hours * (-1); 
      minutes = minutes * (-1); 
     } 
     TimeSpan t = new TimeSpan(hours, minutes, 0); 
     return t.TotalHours; 
    } 

public static int GetNumbersAsInt(String input) 
     { 
      String output = String.Empty; 
      Char[] chars = input.ToCharArray(0, input.Length); 
      for (int i = 0; i < chars.Length; i++) 
      { 
       if (Char.IsNumber(chars[i]) == true) 
        output = output + chars[i]; 
      } 
      return int.Parse(output); 
     } 

uso

double result = GetTotalHours("30:15"); 
double result2 = GetTotalHours("-30:15"); 
Cuestiones relacionadas