2010-04-28 9 views
22

Jak sparsować ciąg jak 30:15 do TimeSpan w C#? 30:15 oznacza 30 godzin i 15 minut.Jak sparsować ciąg z godzinami większymi niż 24 do TimeSpan?

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

To nie wydaje się zbyt eleganckie.

+0

to trzeba wspierać lokalizację? (np. 30.15 zgodnie z ustawieniami językowymi) –

+0

Format będzie zawsze hh: mm, ale hh może być> 24. – jlp

+0

Zobacz to [pytanie] (http://stackoverflow.com/questions/26760/c-parse-string do czasu) (duplikat). – Ando

Odpowiedz

24

Jeśli masz pewność, że zawsze będzie w formacie „HH: mm”, a następnie spróbować czegoś takiego:

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

brzydki, ale myślę, że to sposób na zrobienie tego. dzięki – invalidusername

+2

to nie działa z ujemnym przedziałem czasu (-35: 15 dałoby -34: 45) – fubo

+0

dobrze C# TimeSpan działa, ale jak byś przechował tę wartość w MSSQL? Czas (7) nie działa, a ciąg nie byłby taki przyjemny. – MaxW

0

Normalnie można by użyć TimeSpan.ParseExact gdzie wymagany jest określony format. Ale jedynymi formatami godzin, które można określić są jako części dni (patrz Custom TimeSpan Format Strings).

Dlatego trzeba będzie zrobić samemu:

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

(ale z pewnymi sprawdzanie błędów).

Konstruktor trzy całkowitą horyzont czasowy pozwala godzin> = 24 przelewał do liczby dni.

4

podobne do odpowiedzi Luke'a:

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

Oczywiście przyjmuje przy łańcuch jest sensowne (składającego się z dwóch części oddzielonych od siebie grubego i parsable do ilości całkowitej).

+0

Sądzę, że jeden z uchwytów Luke'a> 99, nieprawdaż? – jlp

+0

@Erik, @jlp: Tak, moje obsługuje godziny większe niż 99, ale moja oryginalna odpowiedź nie była (zanim edytowałem to pół godziny temu). Może Erik patrzył na starą odpowiedź. – LukeH

+0

@Luke: Yup!Dokładnie tak, jak tu odpowiedziałeś;) –

3

Używam prosty sposób, że wymyślił dawno temu i po prostu pisał dzisiaj na moim blogu:

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

To może obsłużyć o wiele więcej sytuacji niż prostszych rozwiązań przewidzianych wcześniej, ale ma swoje własne niedociągnięcia. Omówię to dalej: here.

Teraz, jeśli jesteś w .NET 4 można skrócić realizację ToTimeSpan do:

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

Można nawet uczynić go jedną wkładkę, jeśli nie przeszkadza stan poziomego ekranu ..

+0

Rozwiązanie jest OK, jeśli problem jest dokładnie taki, jak opisano w pytaniu. Ale jeśli wartość łańcucha TimeSpan jest podobna "1.06: 00: 00", to rozwiązanie nie powiedzie się. Niestety link wyjaśniający niedociągnięcia nie działa. Meybe ta kwestia jest tam omawiana. – Florian

+0

@Florian Przenoszę mojego bloga na nowy (i lepszy) host, dlatego na razie jest offline! Nie obsługuje dni, tylko godzin. Tak więc, jeśli chcesz 24 + 6 godzin, będziesz musiał użyć 30:00:00. Pomysł polegał na tym, by unikać całych dni. Niedociągnięcia mają więcej wspólnego z brakiem wartości ujemnych ... – Loudenvier

1

Podobna do odpowiedzi Lukesa, o wiele więcej kodu i miejsca na ulepszenia. ALE radzi sobie również z liczbami ujemnymi ("-30: 15"), więc może może komuś pomóc.

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

Wykorzystanie

double result = GetTotalHours("30:15"); 
double result2 = GetTotalHours("-30:15"); 
Powiązane problemy