2010-04-28 10 views
22

Come analizzare una stringa come 30:15 in TimeSpan in C#? 30:15 significa 30 ore e 15 minuti.Come analizzare la stringa con ore superiori a 24 su TimeSpan?

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

Questo non sembra troppo elegante.

+0

Ha bisogno di supportare la localizzazione? (ad esempio 30.15 in base alle impostazioni della lingua) –

+0

Il formato sarà sempre hh: mm ma hh potrebbe essere> 24. – jlp

+0

Vedere questa [domanda] (http://stackoverflow.com/questions/26760/c-parse-string -to-timespan) (duplicato). – Ando

risposta

24

Se si è certi che il formato sarà sempre "HH: mm" quindi provare qualcosa di simile:

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

brutto, ma credo che sia il modo di farlo. grazie – invalidusername

+2

questo non funziona con un intervallo di tempo negativo (-35: 15 risulterebbe in -34: 45) – fubo

+0

bene C# TimeSpan funziona, ma come si memorizzerebbe questo valore in MSSQL? Il tempo (7) non funziona e lo spago non sarebbe così bello. – MaxW

0

Normalmente si potrebbe usare TimeSpan.ParseExact in cui è richiesto un formato specifico. Ma i soli formati di ore che possono essere specificati sono come parti di giorni (vedere Custom TimeSpan Format Strings).

Pertanto è necessario fare il lavoro da soli:

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

(Ma con un po 'di controllo degli errori.)

Il costruttore tre intero di periodo consente ore> = 24 traboccante nel conteggio giorni.

4

simili risposta di Luca:

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

Ovviamente assume la stringa originale è ben formata (composto di due parti separate da due punti e analizzabili ad un numero intero).

+0

Riconosco le maniglie di Luke> 99, vero? – jlp

+0

@Erik, @jlp: Sì, la mia gestisce le ore superiori a 99 semplicemente bene, anche se la mia risposta originale no (prima che l'avessi modificata mezz'ora fa). Forse Erik stava guardando la vecchia risposta. – LukeH

+0

@Luke: Yup!Esattamente come hai risposto qui;) –

3

sto usando un metodo semplice che ho ideato un molto tempo fa e appena postato oggi sul mio 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); 
    } 
} 

Questo in grado di gestire molte più situazioni rispetto alle soluzioni più semplici fornite prima, ma ha il suo proprie carenze. Ne discuto ulteriormente here.

Ora, se siete in .NET 4 è possibile abbreviare l'implementazione ToTimeSpan a:

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

Si può anche fare un one-liner, se non ti dispiace utilizzando state orizzontale dello schermo ..

+0

La soluzione è OK se il problema è esattamente come descritto nella domanda. Ma se il valore della stringa TimeSpan è come "1.06: 00: 00", questa soluzione ha esito negativo. Sfortunatamente il collegamento che spiega le carenze non funziona. Meybe questo problema è discusso lì. – Florian

+0

@Florian Sto spostando il mio blog su un nuovo (e migliore) host, ecco perché è offline per ora! Non supporta giorni, solo ore. Quindi, se vuoi 24 + 6 ore, dovrai usare le 30:00:00. L'idea era di evitare l'uso di giorni del tutto. Le carenze hanno più a che fare con il non sostenere i valori negativi ... – Loudenvier

1

Simile alla risposta di Lukes, con molto più codice e margini di miglioramento. MA si occupa di ore negative ("-30: 15"), quindi forse può aiutare qualcuno.

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

utilizzo

double result = GetTotalHours("30:15"); 
double result2 = GetTotalHours("-30:15"); 
Problemi correlati